Description:
add some lock in task git-svn-id: http://theory.cpe.ku.ac.th/grader/web/trunk@55 6386c4cd-e34a-4fa8-8920-d93eb39b512e
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r30:c1451a367614 - - 9 files changed: 170 inserted, 7 deleted

@@ -0,0 +1,17
1 + class AddStatusToTasks < ActiveRecord::Migration
2 + def self.up
3 + add_column :tasks, :status, :integer
4 + add_column :tasks, :updated_at, :datetime
5 +
6 + Task.reset_column_information
7 + Task.find(:all).each do |task|
8 + task.status_complete
9 + task.save
10 + end
11 + end
12 +
13 + def self.down
14 + remove_column :tasks, :updated_at
15 + remove_column :tasks, :status
16 + end
17 + end
@@ -0,0 +1,16
1 + ENV["RAILS_ENV"] = "test"
2 + require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
3 +
4 + def take_wait_return
5 + task = Task.get_inqueue_and_change_status(Task::STATUS_GRADING)
6 + sleep (rand)/10.0
7 + task.status_complete
8 + task.save!
9 + end
10 +
11 + n = 300
12 +
13 + n.times do |i|
14 + take_wait_return
15 + puts i
16 + end
@@ -0,0 +1,18
1 + ENV["RAILS_ENV"] = "test"
2 + require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
3 +
4 + def clear_all_tasks
5 + Task.find(:all).each do |task|
6 + task.destroy
7 + end
8 + end
9 +
10 +
11 + clear_all_tasks
12 +
13 + (1..1000).each do |i|
14 + Task.create(:id => i,
15 + :submission_id => i,
16 + :status => Task::STATUS_INQUEUE)
17 + end
18 +
@@ -0,0 +1,14
1 + ENV["RAILS_ENV"] = "test"
2 + require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
3 +
4 + def clear_all_tasks
5 + Task.find(:all).each do |task|
6 + task.destroy
7 + end
8 + end
9 +
10 + puts Task.find(:all,
11 + :conditions => {:status => Task::STATUS_COMPLETE}).length
12 +
13 + clear_all_tasks
14 +
@@ -1,2 +1,40
1 class Task < ActiveRecord::Base
1 class Task < ActiveRecord::Base
2 +
3 + STATUS_GRADING = 0
4 + STATUS_INQUEUE = 1
5 + STATUS_COMPLETE = 2
6 +
7 + def status_inqueue
8 + self.status = Task::STATUS_INQUEUE
9 + end
10 +
11 + def status_grading
12 + self.status = Task::STATUS_GRADING
13 + end
14 +
15 + def status_complete
16 + self.status = Task::STATUS_COMPLETE
17 + end
18 +
19 + def self.get_inqueue_and_change_status(status)
20 + task = nil
21 + begin
22 + Task.transaction do
23 + task = Task.find(:first,
24 + :order => "created_at",
25 + :conditions => {:status=> Task::STATUS_INQUEUE},
26 + :lock => true)
27 + if task!=nil
28 + task.status = status
29 + task.save!
30 + end
31 + end
32 +
33 + rescue
34 + task = nil
35 +
36 + end
37 + task
38 + end
39 +
2 end
40 end
@@ -1,7 +1,8
1 class AddLanguageExt < ActiveRecord::Migration
1 class AddLanguageExt < ActiveRecord::Migration
2 def self.up
2 def self.up
3 add_column :languages, :ext, :string, :limit => 10
3 add_column :languages, :ext, :string, :limit => 10
4 -
4 +
5 + Language.reset_column_information
5 langs = Language.find(:all)
6 langs = Language.find(:all)
6 langs.each do |l|
7 langs.each do |l|
7 l.ext = l.name
8 l.ext = l.name
@@ -9,7 +9,7
9 #
9 #
10 # It's strongly recommended to check this file into your version control system.
10 # It's strongly recommended to check this file into your version control system.
11
11
12 - ActiveRecord::Schema.define(:version => 14) do
12 + ActiveRecord::Schema.define(:version => 15) do
13
13
14 create_table "grader_processes", :force => true do |t|
14 create_table "grader_processes", :force => true do |t|
15 t.string "ip", :limit => 20
15 t.string "ip", :limit => 20
@@ -89,6 +89,8
89 create_table "tasks", :force => true do |t|
89 create_table "tasks", :force => true do |t|
90 t.integer "submission_id"
90 t.integer "submission_id"
91 t.datetime "created_at"
91 t.datetime "created_at"
92 + t.integer "status"
93 + t.datetime "updated_at"
92 end
94 end
93
95
94 create_table "users", :force => true do |t|
96 create_table "users", :force => true do |t|
@@ -1,5 +1,31
1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 - one:
2 +
3 + sub1:
3 id: 1
4 id: 1
4 - two:
5 + submission_id: 1
6 + status: <%= Task::STATUS_COMPLETE %>
7 + created_at: <%= Time.local(2000,1,1,10,10) %>
8 +
9 + sub2:
5 id: 2
10 id: 2
11 + submission_id: 2
12 + status: <%= Task::STATUS_GRADING %>
13 + created_at: <%= Time.local(2000,1,1,10,20) %>
14 +
15 + sub3:
16 + id: 3
17 + submission_id: 3
18 + status: <%= Task::STATUS_INQUEUE %>
19 + created_at: <%= Time.local(2000,1,1,10,30) %>
20 +
21 + sub4:
22 + id: 4
23 + submission_id: 4
24 + status: <%= Task::STATUS_INQUEUE %>
25 + created_at: <%= Time.local(2000,1,1,10,40) %>
26 +
27 + sub5:
28 + id: 5
29 + submission_id: 5
30 + status: <%= Task::STATUS_INQUEUE %>
31 + created_at: <%= Time.local(2000,1,1,10,50) %>
@@ -3,8 +3,39
3 class TaskTest < Test::Unit::TestCase
3 class TaskTest < Test::Unit::TestCase
4 fixtures :tasks
4 fixtures :tasks
5
5
6 - # Replace this with your real tests.
6 + self.use_transactional_fixtures = false
7 - def test_truth
7 +
8 - assert true
8 + def test_get_inqueue_simple
9 + task1 = Task.get_inqueue_and_change_status(Task::STATUS_GRADING)
10 +
11 + assert_equal task1.id, 3, "should get the earliest task"
12 + assert_equal task1.status, Task::STATUS_GRADING, "status changes"
13 +
14 + task2 = Task.get_inqueue_and_change_status(Task::STATUS_GRADING)
15 +
16 + assert_equal task2.id, 4, "should get the next task"
17 + assert_equal task2.status, Task::STATUS_GRADING, "status changes"
9 end
18 end
19 +
20 + def generate_tasks(n)
21 + n.times do |i|
22 + Task.create(:submission_id => i,
23 + :status => Task::STATUS_INQUEUE,
24 + :create_at => Time.now + i.minutes)
25 + end
26 + end
27 +
28 + # use the process version in /test/concurrent instead
29 + def UNUSED_test_get_inqueue_concurrent
30 + ActiveRecord::Base.allow_concurrency = true
31 +
32 + task1 = Task.get_inqueue_and_change_status(Task::STATUS_GRADING)
33 +
34 + assert_equal task1.id, 3, "should get the earliest task"
35 + assert_equal task1.status, Task::STATUS_GRADING, "status changes"
36 +
37 + ActiveRecord::Base.verify_active_connections!
38 + end
39 +
10 end
40 end
41 +
You need to be logged in to leave comments. Login now