Skip to content

Commit

Permalink
process_hits is now protected with a lockfile to prevent more than on…
Browse files Browse the repository at this point in the history
…e instance being spawned if someone sets up the rake task as a cronjob.
  • Loading branch information
aantix committed Sep 27, 2010
1 parent eb5b061 commit 0d54e2a
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 38 deletions.
2 changes: 1 addition & 1 deletion LICENSE
@@ -1,4 +1,4 @@
Copyright (c) 2009 Jim Jones
Copyright (c) 2010 Jim Jones

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
Expand Down
10 changes: 8 additions & 2 deletions README.rdoc
Expand Up @@ -28,7 +28,7 @@ And add it to your environment.rb configuration as a gem dependency:
To access the Turkee rake tasks, add the following to your application's Rakefile:
require 'tasks/turkee'

Run the turkee generator from your application directory to copy the needed javascript file into your application:
Run the turkee generator from your application directory to copy the needed javascript file and migrations into your application:

./script/generate turkee # Rails 2
## Support for Rails 3 in the future.
Expand Down Expand Up @@ -67,7 +67,13 @@ Using the turkee_form_for helper will post the form to the Mechanical Turk sandb
6) Run the rake task that retrieves the values from Mechanical Turk and stores the user entered values into your model.
rake turkee::getresults

Rerun this task to see your data come in (run it as a cronjob if you'd like).
Rerun this task periodically to retrieve newly entered form values. You can setup this task as a cronjob to automate this.

crontab -e

# E.g. run every five minutes
*/5 * * * * cd /var/www/your/turk/application && rake turkee:getresults


7) When a response is retrieved from Mechanical Turk, Turkee attempts to create a data row for the model specified using the corresponding retrieved data. If the row cannot be created, the assignment is rejected.
As for approval, if the row is created and you haven't specified your own custom approve? method for the model the assignment will automatically be approved. If you'd like to add your own custom approval method, add the approve? instance method to your model. E.g. :
Expand Down
8 changes: 3 additions & 5 deletions Rakefile
Expand Up @@ -8,14 +8,11 @@ begin
========================================================================
Turkee Installation Complete.
------------------------------------------------------------------------
Please run the generator to copy the needed javascript file
into your application:
rails generator turkee:install # Rails 3
./script/generate turkee # Rails 2
For instructions on gem usage, visit:
http://github.com/aantix/turkee#readme
========================================================================
-- Gobble, gobble.
}

require 'jeweler'
Expand All @@ -27,7 +24,8 @@ begin
gem.homepage = "http://github.com/aantix/turkee"
gem.authors = ["Jim Jones"]
gem.add_development_dependency "rspec", ">= 1.2.9"
gem.add_development_dependency "rturk", ">= 2.3.0"
gem.add_development_dependency "rturk", ">= 2.3.0"
gem.add_development_dependency "lockfile", ">= 1.4.3"
gem.post_install_message = INSTALL_MESSAGE
gem.require_path = 'lib'
gem.files = %w(MIT-LICENSE README.textile Rakefile init.rb) + Dir.glob("{generators,lib,spec}/**/*")
Expand Down
68 changes: 38 additions & 30 deletions lib/turkee.rb
Expand Up @@ -26,39 +26,47 @@ def self.form_url(typ)
# Each specific TurkeeTask object (determined by task_type field) is in charge of
# accepting/rejecting the assignment and importing the data into their respective tables.
def self.process_hits
turks = TurkeeTask.unprocessed_hits

turks.each do |turk|
hit = RTurk::Hit.new(turk.hit_id)

hit.assignments.each do |assignment|
next if assignment.status != 'Submitted'
next if TurkImportedAssignment.find_by_assignment_id(assignment.id).count > 0

model = Object::const_get(turk.task_type)

# ruby-1.8.7-p302 > Rack::Utils.parse_nested_query("authenticity_token=TfWm9jaKPxjzHHF0YscG4K29S3%2B0n86ii%2Fo4Nh3piJo%3D&survey%5Bresponse%5D=4444&commit=Create")
# => {"commit"=>"Create", "authenticity_token"=>"TfWm9jaKPxjzHHF0YscG4K29S3+0n86ii/o4Nh3piJo=", "survey"=>{"response"=>"4444"}}
#
params = assignment.answers.map{|k,v| "#{CGI::escape(k)}=#{CGI::escape(v)}"}.join('&')
param_hash = Rack::Utils.parse_nested_query(params)
result = model.create(param_hash)

# If there's a custom approve? method, see if we should approve the submitted assignment
# otherwise just approve it by default
if result.errors.size > 0
assignment.reject!('Failed to enter proper data.')
elsif result.responds_to?(:approve?)
result.approve? ? assignment.approve!('') : assignment.reject!('')
else
assignment.approve!('')
end

TurkeeImportedAssignment.create(:assignment_id => assignment.id)
begin
Lockfile.new('/tmp/turk_processor.lock', :retries => 0) do

end
turks = TurkeeTask.unprocessed_hits

turks.each do |turk|
hit = RTurk::Hit.new(turk.hit_id)

hit.assignments.each do |assignment|
next if assignment.status != 'Submitted'
next if TurkImportedAssignment.find_by_assignment_id(assignment.id).count > 0

model = Object::const_get(turk.task_type)

# ruby-1.8.7-p302 > Rack::Utils.parse_nested_query("authenticity_token=TfWm9jaKPxjzHHF0YscG4K29S3%2B0n86ii%2Fo4Nh3piJo%3D&survey%5Bresponse%5D=4444&commit=Create")
# => {"commit"=>"Create", "authenticity_token"=>"TfWm9jaKPxjzHHF0YscG4K29S3+0n86ii/o4Nh3piJo=", "survey"=>{"response"=>"4444"}}
#
params = assignment.answers.map { |k, v| "#{CGI::escape(k)}=#{CGI::escape(v)}" }.join('&')
param_hash = Rack::Utils.parse_nested_query(params)
result = model.create(param_hash)

# If there's a custom approve? method, see if we should approve the submitted assignment
# otherwise just approve it by default
if result.errors.size > 0
assignment.reject!('Failed to enter proper data.')
elsif result.responds_to?(:approve?)
result.approve? ? assignment.approve!('') : assignment.reject!('')
else
assignment.approve!('')
end

TurkeeImportedAssignment.create(:assignment_id => assignment.id)

# hit.dispose!
end

# hit.dispose!
end
end
rescue Lockfile::MaxTriesLockError => e
# logger.info "Turk process is already running. Exiting."
end

end
Expand Down

0 comments on commit 0d54e2a

Please sign in to comment.