noda 0.0.1 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -1,6 +1,8 @@
1
1
  = noda
2
2
 
3
- Description goes here.
3
+ Noda �̓V���v���ȃW���u�L���[�T�[�o�[�ł�.
4
+
5
+ druby���g�p���āC�}���`�X���b�h�𕪎U�T�[�o�Ŏ������Ă��܂��D
4
6
 
5
7
  == Contributing to noda
6
8
 
@@ -14,6 +16,6 @@ Description goes here.
14
16
 
15
17
  == Copyright
16
18
 
17
- Copyright (c) 2011 takuya. See LICENSE.txt for
19
+ Copyright (c) 2011 takuya_1st. See LICENSE.txt for
18
20
  further details.
19
21
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.5
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created on 2011-5-12.
4
+ # Copyright (c) 2011. All rights reserved.
5
+ #
6
+
7
+ require 'rubygems'
8
+ require 'daemons'
9
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/noda")
10
+ KCODE='s'
11
+ options = {
12
+ :dir_mode => :script,
13
+ :dir => '/var/run',
14
+ :multiple => true,
15
+ :ontop => false,
16
+ :mode => :exec,
17
+ :backtrace => true,
18
+ :monitor => true
19
+ }
20
+ require "socket"
21
+ ip= IPSocket::getaddress(Socket::gethostname)
22
+ STDOUT.puts " job_monitor at http://#{ip}:10080"
23
+ STDOUT.puts " job_server at druby://#{ip}:10001"
24
+ Daemons.run_proc("job_server",options){
25
+ m=Noda::JobMonitor.new("#{ip}","10080","druby://#{ip}:10001")
26
+ m.start_monitor
27
+ s=Noda::JobServer.new("#{ip}", "10001")
28
+ s.start_service
29
+ }
30
+
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created on 2011-5-12.
4
+ # Copyright (c) 2011. All rights reserved.
5
+ #
6
+
7
+ require 'rubygems'
8
+ require 'daemons'
9
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/noda")
10
+ KCODE='s'
11
+ options = {
12
+ :dir_mode => :script,
13
+ :dir => '/var/run',
14
+ :multiple => true,
15
+ :ontop => false,
16
+ :mode => :exec,
17
+ :backtrace => true,
18
+ :monitor => true
19
+ }
20
+ require "socket"
21
+ ip= IPSocket::getaddress(Socket::gethostname)
22
+ STDOUT.puts " connect to job_server at druby://#{ip}:10001"
23
+ Daemons.call(options){
24
+ s=Noda::JobWorker.new("#{ip}", "10001")
25
+ s.start_service
26
+ }
27
+
@@ -0,0 +1,71 @@
1
+
2
+ module Noda
3
+
4
+ class JobMonitor
5
+ require 'webrick'
6
+ require 'drb/drb'
7
+ attr_accessor :job_server, :web_server
8
+ def initialize(addr="localhost",port="10080",job_server="druby://localhost:10001")
9
+ @job_server = DRbObject.new_with_uri(job_server)
10
+ @addr = addr
11
+ @port = port
12
+ self.init_webrick
13
+ end
14
+ def start_monitor
15
+ trap("INT"){ @web_server.shutdown }
16
+ @thread = Thread.new{ @web_server.start}
17
+ end
18
+ def stop_monitor
19
+ @web_server.stop
20
+ end
21
+ def init_webrick
22
+ config = WEBrick::Config::HTTP
23
+ config[:Port] = @port
24
+ config[:BindAddress]=@addr
25
+ config[:AccessLog] = WEBrick::Log.new("/dev/null",1) #���O�v��Ȃ��D
26
+ config[:Logger] = Logger.new("/dev/null") #���O�v��Ȃ��D
27
+ @web_server = WEBrick::HTTPServer.new(config)
28
+ @web_server.mount_proc '/' do |req,res|
29
+ res.content_type="text/plain"
30
+ res.body = "running" if @job_server.alive?
31
+ res.body = "stopped" unless @job_server.alive?
32
+ end
33
+ @web_server.mount_proc '/in_queue' do |req,res|
34
+ res.content_type="text/plain"
35
+ if req.path_info =~ %r'^/(\d+)$' then
36
+ num = $1.to_i
37
+ res.body = @job_server.input._at(num).to_s
38
+ end
39
+ if req.path_info =~ %r'^/$' then
40
+ res.body = @job_server.input.size.to_s
41
+ end
42
+ end
43
+ @web_server.mount_proc '/out_queue' do |req,res|
44
+ res.content_type="text/plain"
45
+ if req.path_info =~ %r'^/(\d+)$' then
46
+ num = $1.to_i
47
+ res.body = @job_server.output._at(num).to_s
48
+ end
49
+ if req.path_info =~ %r'^/$' then
50
+ res.body = @job_server.output.size.to_s
51
+ end
52
+ end
53
+ @web_server.mount_proc '/hash_table' do |req,res|
54
+ res.content_type="text/plain"
55
+ res.body = @job_server.hash_table.size.to_s
56
+ end
57
+ @web_server.mount_proc '/hash_table/keys' do |req,res|
58
+ res.content_type="text/plain"
59
+ res.body = @job_server.hash_table.keys.inspect
60
+ end
61
+ @web_server.mount_proc '/hash_table/fetch' do |req,res|
62
+ res.content_type="text/plain"
63
+ if req.path_info =~ %r'^/([^/]+)$' then
64
+ key = $1.to_s
65
+ res.body = @job_server.hash_table.get(key).to_s
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,39 @@
1
+ module Noda
2
+
3
+ class JobServer
4
+ include DRb::DRbUndumped
5
+ attr_reader :thread, :server
6
+ def initialize( addr='localhost', port='10001',acl=nil,log_file=STDOUT )
7
+ @q_in = RQueue.new()
8
+ @q_out = RQueue.new()
9
+ @hash_table = Table.new()
10
+ @server = DRb.start_service("druby://#{addr}:#{port}",self)
11
+ @thread = @server.thread
12
+ @logger = Logger.new(log_file)
13
+ end
14
+ def stop
15
+ @server.stop_service
16
+ end
17
+ def alive?
18
+ @server.alive?
19
+ end
20
+ def input
21
+ #�T�[�o�[�͕K���C���v�b�g�L���[��Ԃ�
22
+ @q_in
23
+ end
24
+ def output
25
+ @q_out
26
+ end
27
+ def hash_table
28
+ @hash_table
29
+ end
30
+ def start_service
31
+ @thread.join
32
+ end
33
+ def logger
34
+ @logger
35
+ end
36
+ end
37
+
38
+
39
+ end
@@ -0,0 +1,60 @@
1
+ module Noda
2
+
3
+
4
+ class JobWorker
5
+ attr_reader :thread
6
+ attr_accessor :max_retry_connect , :wait_time_to_retry
7
+ def initialize( job_server_addr="localhost",job_server_port="10001" )
8
+ @server_uri = "druby://#{job_server_addr}:#{job_server_port}"
9
+ @max_retry_connect = 30
10
+ @wait_time_to_retry = 2
11
+ require "socket"
12
+ @local_addr = IPSocket::getaddress(Socket::gethostname)
13
+ self.connect
14
+ end
15
+ def connect_job_server
16
+ error_conter = 0
17
+ begin
18
+ @job =DRbObject.new_with_uri(@server_uri)
19
+ @job.hash_table
20
+ @logger = @job.logger
21
+ rescue DRb::DRbConnError => e
22
+ error_conter +=1
23
+ raise e if error_conter > @max_retry_connect
24
+ sleep @wait_time_to_retry
25
+ retry
26
+ end
27
+ end
28
+ def handle_task()
29
+ # @logger.info("self.class@#{@local_addr}#{self.object_id}"){"i try to pop a task."}
30
+ task = @job.input.pop
31
+ # @logger.info("self.class@#{@local_addr}#{self.object_id}"){"i got a task-#{task.name}"}
32
+ # @logger.info("self.class@#{@local_addr}#{self.object_id}"){"i start handling a task-#{task.name}"}
33
+ result = task.do_task(@job.hash_table)
34
+ @job.output.push result
35
+ end
36
+ def init_thread
37
+ @table = @job.hash_table
38
+ @thread= Thread.new{
39
+ loop{
40
+ self.handle_task()
41
+ sleep 0.001
42
+ }
43
+ }
44
+ end
45
+ def connect
46
+ self.connect_job_server
47
+ end
48
+ def start
49
+ self.init_thread
50
+ @thread.join
51
+ end
52
+ def status
53
+ @thread.status if @thread
54
+ end
55
+ def stop
56
+ @thread.kill
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,53 @@
1
+ # -*- utf8 -*-
2
+
3
+ module Noda
4
+ require 'monitor'
5
+ class RQueue
6
+ include DRb::DRbUndumped
7
+ attr_reader :name
8
+ def initialize( max=nil, name=nil )
9
+ @name = name
10
+ @list = []
11
+ @max = nil
12
+ @max = max if max
13
+ self.extend(MonitorMixin)
14
+ @m_empty = self.new_cond
15
+ @m_full = self.new_cond
16
+ end
17
+ def push obj
18
+ self.synchronize{
19
+ @m_full.wait_while{ self.full? } if @max
20
+ @list.push obj
21
+ @m_empty.broadcast
22
+ }
23
+ end
24
+ def pop
25
+ self.synchronize{
26
+ @m_empty.wait_while{ self.empty? }
27
+ obj = @list.shift
28
+ @m_full.broadcast if @max
29
+ obj
30
+ }
31
+ end
32
+ def include?(v) @list.include? v end
33
+ alias exists? include?
34
+ def firsts(n=1) (0...n).map{self.pop} end
35
+ def first() self.pop end
36
+ def size() @list.size end
37
+ def max_size() @max end
38
+ def empty?() @list.empty? end
39
+ def close_to_full?() @list.size >= @max-5 end
40
+ def full?()
41
+ # max=nil �Ȃ�Limitless�B�‚܂薳����
42
+ @list.size >= @max if @max
43
+ end
44
+ def all() self.firsts(self.size) end
45
+ # �P����m�܂ł̒l�����B�O�n�܂�łȂ����Ƃɒ���
46
+ def _at(pos)
47
+ i = pos - 1
48
+ return @list.at(i) if (i) < self.size
49
+ end
50
+ end
51
+
52
+
53
+ end
data/lib/noda/table.rb ADDED
@@ -0,0 +1,54 @@
1
+ #
2
+ module Noda
3
+ #スレッドセーフなHASHテーブルを作ってる
4
+ #内部的にはHashにしている
5
+ #KVSとして使っている
6
+ #TODO::HASHとして動くようにEnumerableを実装したい
7
+ #TODO::DBやファイルに保存する。このクラスAPIでアクセス出来るアダプタを作りたい
8
+ class Table
9
+ include DRb::DRbUndumped
10
+ include Enumerable
11
+ attr_reader :name
12
+ def initialize(name=nil)
13
+ @hash = {}
14
+ @name = name
15
+ self.extend(MonitorMixin)
16
+ @m_lock = self.new_cond
17
+ @saved_keys = []
18
+ end
19
+ def get(key)
20
+ @hash[key][:data]
21
+ end
22
+ def put(key, obj)
23
+ self.synchronize{
24
+ @hash[key] = {:data=>obj,:saved=>false}
25
+ }
26
+ end
27
+ def has_key?(key) @hash.has_key? key end
28
+ alias :exists? :has_key?
29
+ def keys() @hash.keys end
30
+ def size() @hash.size end
31
+ def each
32
+ @hash.each_pair{|k,v| yield( k,v[:data] ) }
33
+ nil
34
+ end
35
+ def saved?(key)
36
+ @hash[key][:saved]
37
+ end
38
+ def update_saved_at(key,status=true)
39
+ self.synchronize{
40
+ @hash[key][:saved]=status
41
+ }
42
+ end
43
+ def each_unsaved_pair
44
+ @hash.each_pair{|k,v| next if v[:saved]; yield( k, v[:data] ) }
45
+ nil
46
+ end
47
+ def has_unsaved_key?
48
+ return true if @hash.find{|k,v| v[:saved]==false}
49
+ return false
50
+ end
51
+ end
52
+
53
+ end
54
+
@@ -0,0 +1,43 @@
1
+ module Noda
2
+
3
+ class TableAutoSaver < JobWorker
4
+ attr_reader :thread
5
+ attr_accessor :max_retry_connect , :wait_time_to_retry
6
+ def initialize( job_server_addr="localhost",job_server_port="10001" )
7
+ super
8
+ @interval = 2
9
+ require 'tmpdir'
10
+ @save_dir = Dir.tmpdir
11
+ end
12
+ def save_dir=(dirname)
13
+ raise ArgumentError, "#{dirname} is not direcotry." unless FileTest.directory? dirname
14
+ @save_dir=dirname
15
+ end
16
+ def save_dir
17
+ @save_dir
18
+ end
19
+ def handle_task()
20
+ sleep @interval
21
+ return unless @table.has_unsaved_key?
22
+ @table.each_unsaved_pair{|k,v|
23
+ self.save(k,v)
24
+ @table.update_saved_at(k,true)
25
+ }
26
+ end
27
+ def save(key,val)
28
+ Dir.chdir(@save_dir){
29
+ open(key.to_s, "w"){|f|
30
+ f.write(Marshal.dump({:key=>key, :data=>val}))
31
+ }
32
+ }
33
+ end
34
+ def interval=(sec)
35
+ @interval=sec
36
+ end
37
+ def interval()
38
+ @interval
39
+ end
40
+ end
41
+
42
+
43
+ end
data/lib/noda/task.rb ADDED
@@ -0,0 +1,21 @@
1
+ module Noda
2
+
3
+ class Task
4
+ #�Q�Ɠn���ɂ������Ƃ��� ���� include ���g��
5
+ # objects-by-reference
6
+ #def by_reference() include DRb::DRbUndumped end
7
+
8
+ #this should be overwrite
9
+ def do_task(hash_table)
10
+ end
11
+ #this should be overwrite
12
+ def name
13
+ return self.object_id unless @name
14
+ return @name if @name
15
+ end
16
+ def name=(str) @name=str end
17
+ end
18
+
19
+
20
+ end
21
+
data/lib/noda.rb CHANGED
@@ -1,15 +1,17 @@
1
1
  require 'rubygems'
2
2
  require 'drb/drb'
3
-
3
+ require 'logger'
4
4
 
5
5
  $:.unshift(File.dirname(__FILE__)) unless
6
6
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
7
7
  require 'noda/rqueue'
8
8
  require 'noda/job_server'
9
+ require 'noda/job_monitor'
9
10
  require 'noda/job_worker'
10
11
  require 'noda/table'
11
12
  require 'noda/task'
12
13
  require 'noda/table'
14
+ require 'noda/table_auto_saver'
13
15
 
14
16
  module Noda
15
17
  #VERSION = '0.0.1'
data/noda.gemspec CHANGED
@@ -5,13 +5,14 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{noda}
8
- s.version = "0.0.1"
8
+ s.version = "0.0.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["takuya"]
12
- s.date = %q{2011-05-18}
12
+ s.date = %q{2011-05-28}
13
13
  s.description = %q{noda is job queue system using druby }
14
14
  s.email = %q{takuya.1st@gmail}
15
+ s.executables = ["noda_job_worker", "noda_job_server"]
15
16
  s.extra_rdoc_files = [
16
17
  "LICENSE.txt",
17
18
  "README.rdoc"
@@ -24,9 +25,26 @@ Gem::Specification.new do |s|
24
25
  "README.rdoc",
25
26
  "Rakefile",
26
27
  "VERSION",
28
+ "bin/noda_job_server",
29
+ "bin/noda_job_worker",
27
30
  "lib/noda.rb",
31
+ "lib/noda/job_monitor.rb",
32
+ "lib/noda/job_server.rb",
33
+ "lib/noda/job_worker.rb",
34
+ "lib/noda/rqueue.rb",
35
+ "lib/noda/table.rb",
36
+ "lib/noda/table_auto_saver.rb",
37
+ "lib/noda/task.rb",
28
38
  "noda.gemspec",
29
- "test/test_noda.rb"
39
+ "test/test_helper.rb",
40
+ "test/test_job_monitor.rb",
41
+ "test/test_job_server.rb",
42
+ "test/test_job_worker.rb",
43
+ "test/test_noda.rb",
44
+ "test/test_rqueue.rb",
45
+ "test/test_table.rb",
46
+ "test/test_table_saver_woker.rb",
47
+ "test/test_task.rb"
30
48
  ]
31
49
  s.homepage = %q{http://github.com/takuya/noda}
32
50
  s.licenses = ["MIT"]
@@ -0,0 +1,14 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require 'rubygems'
4
+ require 'drb/drb'
5
+ require File.dirname(__FILE__) + '/../lib/noda'
6
+
7
+ require 'noda'
8
+ require 'noda/job_server'
9
+ require 'noda/job_worker'
10
+ require 'noda/job_monitor'
11
+ require 'noda/rqueue'
12
+ require 'noda/table'
13
+ require 'noda/task'
14
+ include Noda
@@ -0,0 +1,63 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+ class TestJobMonitor < Test::Unit::TestCase
3
+ #�e�X�g�̓}���`�X���b�h�ōs����̂ŁA�|�[�g�Փ˂���Error�ɂȂ�܂��D
4
+ def test_start_monitor
5
+ #���j�^���N�����邩�ǂ���
6
+ m = JobMonitor.new("localhost","10081")
7
+ t = m.start_monitor
8
+ sleep 0.01
9
+ assert m.web_server.status == :Running
10
+ m.stop_monitor
11
+ sleep 0.01
12
+ assert m.web_server.status == :Shutdown
13
+ end
14
+ def test_monitor_in_queue
15
+ require 'open-uri'
16
+
17
+ m = JobMonitor.new("localhost", "10080")
18
+ t = m.start_monitor
19
+ sleep 0.01
20
+ assert m.web_server.status == :Running
21
+ s = JobServer.new
22
+ s.input.push 1234
23
+ assert open("http://localhost:10080/").read == "running"
24
+ assert open("http://localhost:10080/in_queue/").read == "1"
25
+ s.input.push 1111
26
+ assert open("http://localhost:10080/in_queue/").read == "2"
27
+ assert open("http://localhost:10080/in_queue/1").read == "1234"
28
+ assert open("http://localhost:10080/in_queue/2").read == "1111"
29
+ d = s.input.pop
30
+ assert open("http://localhost:10080/in_queue/").read == "1"
31
+ end
32
+ def test_monitor_out_queue
33
+ require 'open-uri'
34
+
35
+ s = JobServer.new("localhost","100011")
36
+ m = JobMonitor.new("localhost", "10083","druby://localhost:100011")
37
+ t = m.start_monitor
38
+ sleep 0.01
39
+ assert m.web_server.status == :Running
40
+ s.output.push 1234
41
+ assert open("http://localhost:10083/").read == "running"
42
+ assert open("http://localhost:10083/out_queue/").read == "1"
43
+ s.output.push 1111
44
+ assert open("http://localhost:10083/out_queue/").read == "2"
45
+ assert open("http://localhost:10083/out_queue/1").read == "1234"
46
+ assert open("http://localhost:10083/out_queue/2").read == "1111"
47
+ end
48
+ def test_monitor_in_queue
49
+ require 'open-uri'
50
+
51
+ s = JobServer.new("localhost","100012")
52
+ m = JobMonitor.new("localhost", "10084","druby://localhost:100012")
53
+ t = m.start_monitor
54
+ sleep 0.01
55
+ assert m.web_server.status == :Running
56
+ assert open("http://localhost:10084/").read == "running"
57
+ assert open("http://localhost:10084/hash_table/").read == "0"
58
+ s.hash_table.put "1234", "abcdefg"
59
+ assert open("http://localhost:10084/hash_table/").read == "1"
60
+ assert open("http://localhost:10084/hash_table/fetch/1234").read == "abcdefg"
61
+ assert open("http://localhost:10084/hash_table/keys").read == "[\"1234\"]"
62
+ end
63
+ end
@@ -0,0 +1,85 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+
4
+ class TestJobServer < Test::Unit::TestCase
5
+ def test_start_stop_job_server
6
+ #�W���u�}�X�^���N�����邩�ǂ���
7
+ s = JobServer.new
8
+ assert s.alive? == true
9
+ s.stop
10
+ assert s.alive? == false
11
+ end
12
+ def test_job_server_input_queue
13
+ #druby�o�R�Ő������u���b�N����邩�ǂ���
14
+ test_str = "hello world"
15
+ s=JobServer.new
16
+ m = m = DRbObject.new_with_uri('druby://localhost:10001')
17
+ t1 = Thread.new{
18
+ m1 = DRbObject.new_with_uri('druby://localhost:10001')
19
+ q1 = m1.input
20
+ q1.pop
21
+
22
+ }
23
+ #�u���b�N����Ă��邩
24
+ assert t1.status == "sleep"
25
+ m2 = DRbObject.new_with_uri('druby://localhost:10001')
26
+ q2 = m2.input
27
+ q2.push test_str
28
+ #�u���b�N��������ꂩ�ǂ���
29
+ assert t1.status == "run"
30
+ #�T�[�o�[���~
31
+ s.stop
32
+ end
33
+ def test_job_server_output_queue
34
+ #druby�o�R�Ő������u���b�N����邩�ǂ���
35
+ test_str = "hello world"
36
+ s=JobServer.new
37
+ m = m = DRbObject.new_with_uri('druby://localhost:10001')
38
+ t1 = Thread.new{
39
+ m1 = DRbObject.new_with_uri('druby://localhost:10001')
40
+ q1 = m1.output
41
+ q1.pop
42
+
43
+ }
44
+ #�u���b�N����Ă��邩
45
+ assert t1.status == "sleep"
46
+ m2 = DRbObject.new_with_uri('druby://localhost:10001')
47
+ q2 = m2.output
48
+ q2.push test_str
49
+ #�u���b�N��������ꂩ�ǂ���
50
+ assert t1.status == "run"
51
+ #�T�[�o�[���~
52
+ s.stop
53
+ end
54
+ def test_job_server_input_queue_data
55
+ s=JobServer.new
56
+ m = m = DRbObject.new_with_uri('druby://localhost:10001')
57
+ t1 = Thread.new{
58
+ m1 = DRbObject.new_with_uri('druby://localhost:10001')
59
+ q1 = m1.input
60
+ q1.push "hello world"
61
+
62
+ }
63
+ m2 = DRbObject.new_with_uri('druby://localhost:10001')
64
+ q2 = m2.input
65
+ ret = q2.pop
66
+ assert ret == "hello world"
67
+ s.stop
68
+ end
69
+ def test_job_server_output_queue_data
70
+ s=JobServer.new
71
+ m = m = DRbObject.new_with_uri('druby://localhost:10001')
72
+ t1 = Thread.new{
73
+ m1 = DRbObject.new_with_uri('druby://localhost:10001')
74
+ q1 = m1.output
75
+ q1.push "hello world"
76
+
77
+ }
78
+ m2 = DRbObject.new_with_uri('druby://localhost:10001')
79
+ q2 = m2.output
80
+ ret = q2.pop
81
+ assert ret == "hello world"
82
+ s.stop
83
+ end
84
+ end
85
+
@@ -0,0 +1,55 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+ class TestJobWoker < Test::Unit::TestCase
3
+
4
+
5
+ def test_init_job_woker
6
+ worker = JobWorker.new
7
+ assert worker
8
+ end
9
+ #test task
10
+ class MyTask
11
+ def do_task(hash)
12
+ return "test_task_end"
13
+ end
14
+ end
15
+ def test_start_stop
16
+ s =JobServer.new
17
+ w = JobWorker.new
18
+ t = Thread.new{
19
+ w.start
20
+ }
21
+ s.input.push MyTask.new
22
+ ret = s.output.pop
23
+ assert ret == "test_task_end"
24
+ s.stop
25
+ w.stop
26
+ assert w.status == false #�X���b�h�I���ł����H
27
+ end
28
+ def test_do_task
29
+ s=JobServer.new
30
+ worker = JobWorker.new
31
+ s.input.push MyTask.new
32
+ worker.handle_task
33
+ ret = s.output.pop
34
+ assert ret == "test_task_end"
35
+ s.stop
36
+ end
37
+ class MyTask2
38
+ def do_task(hash)
39
+ hash.put "MyTask", "foooo"
40
+ return "test_task_end"
41
+ end
42
+ end
43
+ def test_task_write_hash_table
44
+ #�W���u�T�[�o�[�̋��L�̈�ɏ������߂邩�ǂ���
45
+ s=JobServer.new
46
+ worker = JobWorker.new
47
+ s.input.push MyTask2.new
48
+ worker.handle_task
49
+ ret = s.output.pop
50
+ assert ret == "test_task_end"
51
+ v = s.hash_table.get "MyTask"
52
+ assert v == "foooo"
53
+ s.stop
54
+ end
55
+ end
@@ -0,0 +1,51 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestRQueue < Test::Unit::TestCase
4
+ def setup
5
+ @q = RQueue.new
6
+ end
7
+ def test_RQueue_init
8
+ q = RQueue.new
9
+ assert q.empty?
10
+ end
11
+ def test_RQueue_init_with_RQueue_max_size
12
+ max = 10
13
+ q = RQueue.new max
14
+ assert q.empty? && q.max_size==max
15
+ end
16
+ def test_RQueue_mutex_push
17
+ max = 100
18
+ q = RQueue.new max
19
+ th1 = Thread.new{
20
+ loop{
21
+ q.push 1
22
+ }
23
+ }
24
+ th2 = Thread.new{
25
+ loop{
26
+ q.push 1
27
+ }
28
+ }
29
+ sleep 0.1
30
+ assert th1.status == "sleep" && th2.status == "sleep" && q.full?
31
+ end
32
+ def test_RQueue_mutex_pop
33
+ max = 10
34
+ q = RQueue.new max
35
+ max.times{ q.push 1 }
36
+ th1 = Thread.new{
37
+ loop{
38
+ q.pop
39
+ }
40
+ }
41
+ th2 = Thread.new{
42
+ loop{
43
+ q.pop
44
+ }
45
+ }
46
+ while not q.empty? do
47
+ sleep 0.1
48
+ end
49
+ assert th1.status == "sleep" && th2.status == "sleep" && q.empty?
50
+ end
51
+ end
@@ -0,0 +1,50 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestPageList < Test::Unit::TestCase
4
+ def test_table_put
5
+ list = Table.new
6
+ key,value = "test", "valuevalue"
7
+ list.put key,value
8
+ assert list.get(key) == value
9
+ end
10
+ def test_table_size
11
+ list = Table.new
12
+ assert list.size == 0
13
+ key,value = "test", "valuevalue"
14
+ list.put key,value
15
+ assert list.size == 1
16
+ end
17
+ def test_table_exists
18
+ list = Table.new
19
+ key,value = "test", "valuevalue"
20
+ list.put key,value
21
+ assert list.exists? key
22
+ end
23
+ def test_table_each
24
+ list = Table.new
25
+ data = { "a"=> "aa","b"=>"bv", "c"=> "cc", "d"=> "dd" }
26
+ data.each{|k,v| list.put k,v }
27
+ data.each{|k,v| assert list.get(k) == v }
28
+ list.each{|k,v| assert data[k] == v }
29
+ end
30
+ def test_save_table_data
31
+ list = Table.new
32
+ key,value = "test", "valuevalue"
33
+ list.put key,value
34
+ assert list.saved?(key) == false
35
+ list.update_saved_at(key)
36
+ assert list.saved?(key) == true
37
+ end
38
+ def test_table_each_unsaved_pair
39
+ list = Table.new
40
+ data = { "a"=> "aa","b"=>"bb", "c"=> "cc", "d"=> "dd" }
41
+ data.each{|k,v| list.put k,v }
42
+ list.put( "abc","123")
43
+ list.update_saved_at("abc")
44
+ assert list.saved?("abc")
45
+ a={}
46
+ list.each_unsaved_pair{|k,v| a[k]=v }
47
+ assert a.sort == data.sort
48
+ end
49
+
50
+ end
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+ Thread.abort_on_exception=true
3
+
4
+ class TestTableSaverWorker < Test::Unit::TestCase
5
+ def test_table_saver_initialize
6
+ s = JobServer.new("localhost","10001")
7
+ saver = TableAutoSaver.new
8
+ saver.interval = 12
9
+ assert saver.interval == 12
10
+ end
11
+ def test_table_saver_save_dir
12
+ s = JobServer.new("localhost","10002")
13
+ saver = TableAutoSaver.new("localhost","10002")
14
+ begin
15
+ saver.save_dir = Dir.tmpdir + "a"
16
+ rescue => e
17
+ assert e.to_s =~ %r"is not direcotry."
18
+ end
19
+ d = Dir.mktmpdir("table_saver_")
20
+ saver.save_dir = d
21
+ assert saver.save_dir == d
22
+ Dir.rmdir d
23
+ assert FileTest.exists? d == false
24
+ end
25
+ def test_table_saver_save_dir
26
+ s = JobServer.new("localhost","10003")
27
+ saver = TableAutoSaver.new("localhost","10003")
28
+ t1 = saver.init_thread
29
+ t2 = Thread.new{
30
+ s.hash_table.put("aaaa",1234)
31
+ s.hash_table.put("baaa",1234)
32
+ s.hash_table.put("caaa",1234)
33
+ s.hash_table.put("daaa",1234)
34
+ s.hash_table.put("eaaa",1234)
35
+ while(s.hash_table.has_unsaved_key? )
36
+ sleep 0.001
37
+ end
38
+ }
39
+
40
+ t2.join
41
+
42
+ assert s.hash_table.has_unsaved_key? == false
43
+
44
+ end
45
+
46
+ end
data/test/test_task.rb ADDED
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestPageList < Test::Unit::TestCase
4
+ def test_task_name
5
+ t = Task.new
6
+ assert t.name == t.object_id
7
+ t.name = "No.001"
8
+ assert t.name == "No.001"
9
+ end
10
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: noda
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 5
10
+ version: 0.0.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - takuya
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-18 00:00:00 +09:00
18
+ date: 2011-05-28 00:00:00 +09:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -80,8 +80,9 @@ dependencies:
80
80
  version_requirements: *id004
81
81
  description: "noda is job queue system using druby "
82
82
  email: takuya.1st@gmail
83
- executables: []
84
-
83
+ executables:
84
+ - noda_job_worker
85
+ - noda_job_server
85
86
  extensions: []
86
87
 
87
88
  extra_rdoc_files:
@@ -95,9 +96,26 @@ files:
95
96
  - README.rdoc
96
97
  - Rakefile
97
98
  - VERSION
99
+ - bin/noda_job_server
100
+ - bin/noda_job_worker
98
101
  - lib/noda.rb
102
+ - lib/noda/job_monitor.rb
103
+ - lib/noda/job_server.rb
104
+ - lib/noda/job_worker.rb
105
+ - lib/noda/rqueue.rb
106
+ - lib/noda/table.rb
107
+ - lib/noda/table_auto_saver.rb
108
+ - lib/noda/task.rb
99
109
  - noda.gemspec
110
+ - test/test_helper.rb
111
+ - test/test_job_monitor.rb
112
+ - test/test_job_server.rb
113
+ - test/test_job_worker.rb
100
114
  - test/test_noda.rb
115
+ - test/test_rqueue.rb
116
+ - test/test_table.rb
117
+ - test/test_table_saver_woker.rb
118
+ - test/test_task.rb
101
119
  has_rdoc: true
102
120
  homepage: http://github.com/takuya/noda
103
121
  licenses: