noda 0.0.13 → 0.0.14
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 +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
|
-
|