noda 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +8 -2
- data/VERSION +1 -1
- data/lib/noda/job_monitor.rb +11 -5
- data/lib/noda/job_server.rb +41 -0
- data/lib/noda/rqueue.rb +28 -5
- data/lib/noda/table.rb +42 -5
- data/lib/noda/table_auto_saver.rb +20 -0
- data/lib/noda/task.rb +4 -1
- metadata +4 -5
- data/noda.gemspec +0 -76
data/README.rdoc
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
= noda
|
2
2
|
|
3
|
-
Noda
|
3
|
+
Noda is simple Job Queue server
|
4
|
+
|
5
|
+
Noda はシンプルなジョブキューサーバーです.
|
6
|
+
|
7
|
+
|
8
|
+
drubyを使用して,マルチスレッドを分散サーバで実現しています.
|
9
|
+
|
10
|
+
Noda uses druby that make easy to multi threading via network.
|
4
11
|
|
5
|
-
druby���g�p���āC�}���`�X���b�h�U�T�[�o�Ŏ������Ă��܂��D
|
6
12
|
|
7
13
|
== Contributing to noda
|
8
14
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.14
|
data/lib/noda/job_monitor.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
|
2
2
|
module Noda
|
3
|
-
|
4
|
-
#
|
5
|
-
# DRB
|
3
|
+
#=概要
|
4
|
+
# ジョブ状態を監視するWEBサーバーです。
|
5
|
+
# DRBに接続して,キュー残数,共有ハッシュテーブル、キューの中身を見ることが出来ます.
|
6
|
+
# == 使い方
|
7
|
+
# m=Noda::JobMonitor.new("#{ip}","10080","druby://#{ip}:10001")
|
8
|
+
# m.start_monitor
|
9
|
+
# ==コマンドで起動
|
10
|
+
# $ noda_job_server start
|
6
11
|
|
7
12
|
class JobMonitor
|
8
13
|
require 'webrick'
|
@@ -21,12 +26,13 @@ class JobMonitor
|
|
21
26
|
def stop_monitor
|
22
27
|
@web_server.stop
|
23
28
|
end
|
29
|
+
# 内部で使うWEBRickをインスタンス化してマウントします.
|
24
30
|
def init_webrick
|
25
31
|
config = WEBrick::Config::HTTP
|
26
32
|
config[:Port] = @port
|
27
33
|
config[:BindAddress]=@addr
|
28
|
-
config[:AccessLog] = WEBrick::Log.new("/dev/null",1)
|
29
|
-
config[:Logger] = Logger.new("/dev/null")
|
34
|
+
config[:AccessLog] = WEBrick::Log.new("/dev/null",1) #ログ要らない.
|
35
|
+
config[:Logger] = Logger.new("/dev/null") #ログ要らない.
|
30
36
|
@web_server = WEBrick::HTTPServer.new(config)
|
31
37
|
@web_server.mount_proc '/' do |req,res|
|
32
38
|
res.content_type="text/plain"
|
data/lib/noda/job_server.rb
CHANGED
@@ -1,5 +1,34 @@
|
|
1
1
|
module Noda
|
2
2
|
|
3
|
+
# ==�W���u�T�[�o��\���N���X.
|
4
|
+
# ===�W���u�T�[�o�[
|
5
|
+
# +�W���u�T�[�o�[
|
6
|
+
# ++�|�[�g+�A�h���X
|
7
|
+
# ++�C���v�b�g�E�L���[
|
8
|
+
# ++�A�E�g�v�b�g�E�L���[
|
9
|
+
# ++�n�b�V���e�[�u��
|
10
|
+
# �ō\�������
|
11
|
+
# == �W���u�T�[�o�[�̋N��
|
12
|
+
# noda_job_server start
|
13
|
+
# == �W���u�T�[�o�[�Ƀ^�X�N��o�^
|
14
|
+
# require 'drb'
|
15
|
+
# sever = DRbObject.new_with_uri('druby://localhost:10001')
|
16
|
+
# # �^�X�N�N���X��`���T�[�o�[�ɕۑ����ċ��L����
|
17
|
+
# str = %Q'
|
18
|
+
# class Noda::MyTask
|
19
|
+
# def do_task(table)
|
20
|
+
# table.put @name, "#{Process.pid} : #{Time.now}"
|
21
|
+
# return "#{@name} in #{Process.pid} : #{Time.now}"
|
22
|
+
# end
|
23
|
+
# def initialize(name) @name end
|
24
|
+
# end
|
25
|
+
# '
|
26
|
+
# eval(str)
|
27
|
+
# server.add_task_class( task.class.to_s, str)
|
28
|
+
# # �o�^
|
29
|
+
# task = Noda::MyTask.new("test")
|
30
|
+
# server.input.push task
|
31
|
+
#
|
3
32
|
class JobServer
|
4
33
|
include DRb::DRbUndumped
|
5
34
|
attr_reader :thread, :server
|
@@ -18,28 +47,40 @@ class JobServer
|
|
18
47
|
def alive?
|
19
48
|
@server.alive?
|
20
49
|
end
|
50
|
+
# input queue.
|
51
|
+
# +return Noda::RQueue
|
21
52
|
def input
|
22
53
|
#�T�[�o�[�͕K���C���v�b�g�L���[��Ԃ�
|
23
54
|
@q_in
|
24
55
|
end
|
56
|
+
# output . Noda::RQueue
|
57
|
+
# +return Noda::RQueue
|
25
58
|
def output
|
26
59
|
@q_out
|
27
60
|
end
|
61
|
+
# �^�X�N�Ԃŋ��L����n�b�V���e�[�u�� Noda::Table
|
62
|
+
# +return Noda::Table
|
28
63
|
def hash_table
|
29
64
|
@hash_table
|
30
65
|
end
|
31
66
|
def start_service
|
32
67
|
@thread.join
|
33
68
|
end
|
69
|
+
# �W���u�̃��K�[���w�肷��D
|
34
70
|
def logger
|
35
71
|
@logger
|
36
72
|
end
|
73
|
+
# �^�X�N�̃N���X��`�B���[�J�[�ɃN���X��`�𑗐M����B
|
74
|
+
#
|
75
|
+
#
|
37
76
|
def add_task_class(class_name, source_code)
|
38
77
|
@task_class_source_list[class_name] = source_code
|
39
78
|
end
|
79
|
+
# �^�X�N�̃N���X��`�����o���D
|
40
80
|
def task_class(class_name)
|
41
81
|
@task_class_source_list[class_name]
|
42
82
|
end
|
83
|
+
# �o�^�����N���X��`�ꗗ�����o���D
|
43
84
|
def task_class_source_list
|
44
85
|
@task_class_source_list
|
45
86
|
end
|
data/lib/noda/rqueue.rb
CHANGED
@@ -2,13 +2,20 @@
|
|
2
2
|
|
3
3
|
module Noda
|
4
4
|
require 'monitor'
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
5
|
+
# ジョブのキュー実装
|
6
|
+
# キューはスレッドセーフに書いている
|
7
|
+
#
|
8
|
+
# キューから値を取り出すと、キューには残らない。
|
9
|
+
# ==使用法
|
10
|
+
# require 'noda'
|
11
|
+
# server =Noda::JobServer.new
|
12
|
+
# q = server.input #<= Jobサーバーが持ってる
|
13
|
+
# q.push Noda::MyTask.new("hogehgoe")
|
8
14
|
#
|
9
15
|
class RQueue
|
10
16
|
include DRb::DRbUndumped
|
11
17
|
attr_reader :name
|
18
|
+
#
|
12
19
|
def initialize( max=nil, name=nil )
|
13
20
|
@name = name
|
14
21
|
@list = []
|
@@ -18,6 +25,9 @@ class RQueue
|
|
18
25
|
@m_empty = self.new_cond
|
19
26
|
@m_full = self.new_cond
|
20
27
|
end
|
28
|
+
# キュー末尾にオブジェクトを追加。
|
29
|
+
#
|
30
|
+
# キュー満杯時は実行スレッドをWaitさせます。
|
21
31
|
def push obj
|
22
32
|
self.synchronize{
|
23
33
|
@m_full.wait_while{ self.full? } if @max
|
@@ -25,6 +35,9 @@ class RQueue
|
|
25
35
|
@m_empty.broadcast
|
26
36
|
}
|
27
37
|
end
|
38
|
+
# キュー先頭からオブジェクトを取り出す.
|
39
|
+
#
|
40
|
+
# キュー空なら実行スレッドをWaitさせる.
|
28
41
|
def pop
|
29
42
|
self.synchronize{
|
30
43
|
@m_empty.wait_while{ self.empty? }
|
@@ -33,20 +46,30 @@ class RQueue
|
|
33
46
|
obj
|
34
47
|
}
|
35
48
|
end
|
49
|
+
# 実験用メソッド・使わない.
|
36
50
|
def include?(v) @list.include? v end
|
37
51
|
alias exists? include?
|
52
|
+
# キューの先頭N個を取り出す.
|
38
53
|
def firsts(n=1) (0...n).map{self.pop} end
|
54
|
+
# キューの先頭1個を取り出す. pop の別名
|
39
55
|
def first() self.pop end
|
56
|
+
# キューのサイズを取得
|
40
57
|
def size() @list.size end
|
58
|
+
# キュー格納可能数
|
41
59
|
def max_size() @max end
|
60
|
+
# キューに値があるか
|
42
61
|
def empty?() @list.empty? end
|
62
|
+
# キュー満杯が近いときにTrueを返す.
|
43
63
|
def close_to_full?() @list.size >= @max-5 end
|
64
|
+
# キューが満杯かどうか
|
44
65
|
def full?()
|
45
|
-
# max=nil
|
66
|
+
# max=nil ならLimitless。つまり無限大
|
46
67
|
@list.size >= @max if @max
|
47
68
|
end
|
69
|
+
# キューの値全てを取り出す.
|
48
70
|
def all() self.firsts(self.size) end
|
49
|
-
#
|
71
|
+
# キューの先頭N番目の値を調べる.チェック用。
|
72
|
+
# - pos 1からNまでの値を取る。先頭は1 で指定する.0始まりでないことに注意
|
50
73
|
def _at(pos)
|
51
74
|
i = pos - 1
|
52
75
|
return @list.at(i) if (i) < self.size
|
data/lib/noda/table.rb
CHANGED
@@ -1,10 +1,21 @@
|
|
1
1
|
#
|
2
2
|
module Noda
|
3
|
-
|
4
|
-
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
3
|
+
# スレッドセーフなHASHテーブルを作ってる
|
4
|
+
#
|
5
|
+
# ジョブの共有ストレージ.
|
6
|
+
# 内部的にはHashにしている
|
7
|
+
#
|
8
|
+
# KVSとして使う事を想定
|
9
|
+
#
|
10
|
+
# require 'noda'
|
11
|
+
# server =Noda::JobServer.new
|
12
|
+
# table = server.hash_table #<= 自分でインスタンス化しない.Jobサーバーから使う
|
13
|
+
# table.put "key, "value"
|
14
|
+
# タスクから使う場合。
|
15
|
+
# do_task(hash_table)
|
16
|
+
# v = hash_table.get "key"
|
17
|
+
# hash_table.put "key", "value2" # =>更新
|
18
|
+
# end
|
8
19
|
class Table
|
9
20
|
include DRb::DRbUndumped
|
10
21
|
include Enumerable
|
@@ -16,34 +27,60 @@ class Table
|
|
16
27
|
@m_lock = self.new_cond
|
17
28
|
@saved_keys = []
|
18
29
|
end
|
30
|
+
# キー対応した値を取り出す
|
19
31
|
def get(key)
|
20
32
|
@hash[key][:data]
|
21
33
|
end
|
34
|
+
# キーを名前に値を保存する.
|
22
35
|
def put(key, obj)
|
23
36
|
self.synchronize{
|
24
37
|
@hash[key] = {:data=>obj,:saved=>false}
|
25
38
|
}
|
26
39
|
end
|
40
|
+
# キーがテーブルに存在するか
|
27
41
|
def has_key?(key) @hash.has_key? key end
|
42
|
+
# alias to has_key
|
28
43
|
alias :exists? :has_key?
|
44
|
+
# キーを全部取得
|
29
45
|
def keys() @hash.keys end
|
46
|
+
# テーブルの値の数
|
30
47
|
def size() @hash.size end
|
48
|
+
# Enumerable 用。
|
49
|
+
#
|
50
|
+
# drb 経由で呼び出す時は、参照渡しになるので注意
|
31
51
|
def each
|
32
52
|
@hash.each_pair{|k,v| yield( k,v[:data] ) }
|
33
53
|
nil
|
34
54
|
end
|
55
|
+
|
56
|
+
# テーブルの値はDump済みかどうか
|
57
|
+
#
|
58
|
+
# 永続ストレージに書き出すときに
|
59
|
+
# このフラグを使って処理をする
|
35
60
|
def saved?(key)
|
36
61
|
@hash[key][:saved]
|
37
62
|
end
|
63
|
+
# テーブルの値の保存状態を更新する.
|
64
|
+
#
|
65
|
+
# 永続ストレージに書き出すときに
|
66
|
+
# このフラグを使って処理をする
|
38
67
|
def update_saved_at(key,status=true)
|
39
68
|
self.synchronize{
|
40
69
|
@hash[key][:saved]=status
|
41
70
|
}
|
42
71
|
end
|
72
|
+
# テーブルの未保存の値をすべて取り出す.」
|
73
|
+
#
|
74
|
+
# 永続ストレージに書き出すときに
|
75
|
+
# このメソッドを使って処理が出来る
|
43
76
|
def each_unsaved_pair
|
44
77
|
@hash.each_pair{|k,v| next if v[:saved]; yield( k, v[:data] ) }
|
45
78
|
nil
|
46
79
|
end
|
80
|
+
# 未保存の値があるか
|
81
|
+
#
|
82
|
+
# 永続ストレージに書き出すときに
|
83
|
+
# このフラグを使って処理をする
|
47
84
|
def has_unsaved_key?
|
48
85
|
return true if @hash.find{|k,v| v[:saved]==false}
|
49
86
|
return false
|
@@ -1,4 +1,24 @@
|
|
1
1
|
module Noda
|
2
|
+
# ==�W���u�e�[�u���̎����ۑ�
|
3
|
+
# �W���u���[�J�[�̃e�X�g����.
|
4
|
+
# �^�X�N�����s�������[�J�[
|
5
|
+
# �W���u�T�[�o�[�̃e�[�u���ɂ��܂����f�[�^���t�@�C���Ƀ_���v���Ă����܂��D
|
6
|
+
# s = JobServer.new("localhost","10013")
|
7
|
+
# saver = TableAutoSaver.new("localhost","10013")
|
8
|
+
# t1 = saver.init_thread
|
9
|
+
# t2 = Thread.new{
|
10
|
+
# s.hash_table.put("aaaa",1234)# =>�ۑ������
|
11
|
+
# s.hash_table.put("baaa",1234)# =>�ۑ������
|
12
|
+
# s.hash_table.put("caaa",1234)# =>�ۑ������
|
13
|
+
# s.hash_table.put("daaa",1234)# =>�ۑ������
|
14
|
+
# s.hash_table.put("eaaa",1234)# =>�ۑ������
|
15
|
+
# while(s.hash_table.has_unsaved_key? )
|
16
|
+
# sleep 0.001
|
17
|
+
# end
|
18
|
+
# }
|
19
|
+
#
|
20
|
+
# t2.join
|
21
|
+
|
2
22
|
|
3
23
|
class TableAutoSaver < JobWorker
|
4
24
|
attr_reader :thread
|
data/lib/noda/task.rb
CHANGED
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:
|
4
|
+
hash: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 14
|
10
|
+
version: 0.0.14
|
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-06-
|
18
|
+
date: 2011-06-04 00:00:00 +09:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -106,7 +106,6 @@ files:
|
|
106
106
|
- lib/noda/table.rb
|
107
107
|
- lib/noda/table_auto_saver.rb
|
108
108
|
- lib/noda/task.rb
|
109
|
-
- noda.gemspec
|
110
109
|
- test/test_helper.rb
|
111
110
|
- test/test_job_monitor.rb
|
112
111
|
- test/test_job_server.rb
|
data/noda.gemspec
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
-
# -*- encoding: utf-8 -*-
|
5
|
-
|
6
|
-
Gem::Specification.new do |s|
|
7
|
-
s.name = %q{noda}
|
8
|
-
s.version = "0.0.13"
|
9
|
-
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = ["takuya"]
|
12
|
-
s.date = %q{2011-06-03}
|
13
|
-
s.description = %q{noda is job queue system using druby }
|
14
|
-
s.email = %q{takuya.1st@gmail}
|
15
|
-
s.executables = ["noda_job_worker", "noda_job_server"]
|
16
|
-
s.extra_rdoc_files = [
|
17
|
-
"LICENSE.txt",
|
18
|
-
"README.rdoc"
|
19
|
-
]
|
20
|
-
s.files = [
|
21
|
-
".document",
|
22
|
-
"Gemfile",
|
23
|
-
"Gemfile.lock",
|
24
|
-
"LICENSE.txt",
|
25
|
-
"README.rdoc",
|
26
|
-
"Rakefile",
|
27
|
-
"VERSION",
|
28
|
-
"bin/noda_job_server",
|
29
|
-
"bin/noda_job_worker",
|
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",
|
38
|
-
"noda.gemspec",
|
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"
|
48
|
-
]
|
49
|
-
s.homepage = %q{http://github.com/takuya/noda}
|
50
|
-
s.licenses = ["MIT"]
|
51
|
-
s.require_paths = ["lib"]
|
52
|
-
s.rubygems_version = %q{1.5.0}
|
53
|
-
s.summary = %q{noda is job queue system}
|
54
|
-
|
55
|
-
if s.respond_to? :specification_version then
|
56
|
-
s.specification_version = 3
|
57
|
-
|
58
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
59
|
-
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
60
|
-
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
61
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.6.0"])
|
62
|
-
s.add_development_dependency(%q<rcov>, [">= 0"])
|
63
|
-
else
|
64
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
65
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
66
|
-
s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
|
67
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
68
|
-
end
|
69
|
-
else
|
70
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
71
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
72
|
-
s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
|
73
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|