fairy 0.6.0 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/Makefile +1 -0
  2. data/bin/fairy +35 -5
  3. data/ext/extconf.rb +3 -0
  4. data/ext/fairy.c +180 -0
  5. data/ext/fairy.h +94 -0
  6. data/ext/fiber_mon.h +32 -0
  7. data/ext/fixnum-buffer.c +483 -0
  8. data/ext/p-group-by.c +529 -0
  9. data/ext/p-xgroup-by.c +467 -0
  10. data/ext/simple-hash.c +44 -0
  11. data/ext/string-buffer.c +286 -0
  12. data/ext/xmarshaled-queue.c +699 -0
  13. data/ext/xsized-queue.c +528 -0
  14. data/ext/xthread.h +65 -0
  15. data/fairy.gemspec +5 -2
  16. data/lib/fairy.rb +10 -1
  17. data/lib/fairy/client/group-by.rb +57 -2
  18. data/lib/fairy/client/here.rb +2 -1
  19. data/lib/fairy/controller.rb +25 -4
  20. data/lib/fairy/master.rb +17 -3
  21. data/lib/fairy/master/c-basic-group-by.rb +4 -2
  22. data/lib/fairy/master/c-cat.rb +3 -2
  23. data/lib/fairy/master/c-direct-product.rb +5 -3
  24. data/lib/fairy/master/c-filter.rb +5 -3
  25. data/lib/fairy/master/c-group-by.rb +13 -0
  26. data/lib/fairy/master/c-junction.rb +3 -2
  27. data/lib/fairy/master/c-seg-join.rb +3 -1
  28. data/lib/fairy/master/c-seg-shuffle.rb +3 -2
  29. data/lib/fairy/master/c-seg-split.rb +1 -1
  30. data/lib/fairy/master/c-seg-zip.rb +3 -1
  31. data/lib/fairy/master/c-sort.rb +7 -2
  32. data/lib/fairy/master/c-wc.rb +5 -3
  33. data/lib/fairy/node.rb +13 -2
  34. data/lib/fairy/node/p-barrier.rb +1 -1
  35. data/lib/fairy/node/p-basic-group-by.rb +22 -12
  36. data/lib/fairy/node/p-direct-product.rb +4 -2
  37. data/lib/fairy/node/p-filter.rb +8 -7
  38. data/lib/fairy/node/p-find.rb +2 -1
  39. data/lib/fairy/node/p-group-by.rb +17 -6
  40. data/lib/fairy/node/p-inject.rb +3 -2
  41. data/lib/fairy/node/p-output-file.rb +1 -1
  42. data/lib/fairy/node/p-seg-join.rb +2 -1
  43. data/lib/fairy/node/p-seg-zip.rb +2 -1
  44. data/lib/fairy/node/p-single-exportable.rb +3 -1
  45. data/lib/fairy/node/p-sort.rb +4 -2
  46. data/lib/fairy/node/p-task.rb +1 -1
  47. data/lib/fairy/node/p-wc.rb +5 -2
  48. data/lib/fairy/processor.rb +25 -18
  49. data/lib/fairy/share/block-source.rb +12 -2
  50. data/lib/fairy/share/conf.rb +35 -5
  51. data/lib/fairy/share/hash-simple-hash.rb +1 -1
  52. data/lib/fairy/share/log.rb +11 -4
  53. data/lib/fairy/share/pool-dictionary.rb +2 -1
  54. data/lib/fairy/share/port-marshaled-queue.rb +8 -1
  55. data/lib/fairy/share/port.rb +55 -45
  56. data/lib/fairy/share/reference.rb +2 -1
  57. data/lib/fairy/share/varray.rb +3 -1
  58. data/lib/fairy/share/vfile.rb +4 -2
  59. data/lib/fairy/version.rb +1 -1
  60. data/sample/sort.rb +69 -3
  61. data/spec/fairy8_spec.rb +1 -1
  62. data/test/testc.rb +380 -2
  63. data/tools/cap_recipe/Capfile +3 -3
  64. data/tools/fairy_conf_wizard.rb +375 -0
  65. data/tools/fairy_perf_graph.rb +15 -3
  66. data/tools/git-tag +1 -0
  67. data/tools/log-analysis.rb +59 -11
  68. metadata +33 -34
  69. data/ext/simple_hash/extconf.rb +0 -4
  70. data/ext/simple_hash/simple_hash.c +0 -42
data/ext/xthread.h ADDED
@@ -0,0 +1,65 @@
1
+ /**********************************************************************
2
+
3
+ xthread.h -
4
+
5
+ Copyright (C) 2011 Keiju Ishitsuka
6
+ Copyright (C) 2011 Penta Advanced Laboratories, Inc.
7
+
8
+ **********************************************************************/
9
+
10
+
11
+ #define XTHREAD_VERSION "0.1.2"
12
+
13
+ RUBY_EXTERN VALUE rb_mXThread;
14
+ RUBY_EXTERN VALUE rb_cXThreadFifo;
15
+ RUBY_EXTERN VALUE rb_cXThreadConditionVariable;
16
+ RUBY_EXTERN VALUE rb_cXThreadQueue;
17
+ RUBY_EXTERN VALUE rb_cXThreadSizedQueue;
18
+ RUBY_EXTERN VALUE rb_cXThreadMonitor;
19
+ RUBY_EXTERN VALUE rb_cXThreadMonitorCond;
20
+
21
+
22
+ RUBY_EXTERN VALUE rb_xthread_fifo_new(void);
23
+ RUBY_EXTERN VALUE rb_xthread_fifo_empty_p(VALUE);
24
+ RUBY_EXTERN VALUE rb_xthread_fifo_push(VALUE, VALUE);
25
+ RUBY_EXTERN VALUE rb_xthread_fifo_pop(VALUE);
26
+ RUBY_EXTERN VALUE rb_xthread_fifo_clear(VALUE);
27
+ RUBY_EXTERN VALUE rb_xthread_fifo_length(VALUE);
28
+
29
+ RUBY_EXTERN VALUE rb_xthread_cond_new(void);
30
+ RUBY_EXTERN VALUE rb_xthread_cond_signal(VALUE);
31
+ RUBY_EXTERN VALUE rb_xthread_cond_broadcast(VALUE);
32
+ RUBY_EXTERN VALUE rb_xthread_cond_wait(VALUE, VALUE, VALUE);
33
+
34
+ RUBY_EXTERN VALUE rb_xthread_queue_new(void);
35
+ RUBY_EXTERN VALUE rb_xthread_queue_push(VALUE, VALUE);
36
+ RUBY_EXTERN VALUE rb_xthread_queue_pop(VALUE);
37
+ RUBY_EXTERN VALUE rb_xthread_queue_pop_non_block(VALUE);
38
+ RUBY_EXTERN VALUE rb_xthread_queue_empty_p(VALUE);
39
+ RUBY_EXTERN VALUE rb_xthread_queue_clear(VALUE);
40
+ RUBY_EXTERN VALUE rb_xthread_queue_length(VALUE);
41
+
42
+ RUBY_EXTERN VALUE rb_xthread_sized_queue_new(long);
43
+ RUBY_EXTERN VALUE rb_xthread_sized_queue_max(VALUE);
44
+ RUBY_EXTERN VALUE rb_xthread_sized_queue_set_max(VALUE, VALUE);
45
+ RUBY_EXTERN VALUE rb_xthread_sized_queue_push(VALUE, VALUE);
46
+ RUBY_EXTERN VALUE rb_xthread_sized_queue_pop(VALUE);
47
+ RUBY_EXTERN VALUE rb_xthread_sized_queue_pop_non_block(VALUE);
48
+
49
+ RUBY_EXTERN VALUE rb_xthread_monitor_new(void);
50
+ RUBY_EXTERN VALUE rb_xthread_monitor_try_enter(VALUE);
51
+ RUBY_EXTERN VALUE rb_xthread_monitor_enter(VALUE);
52
+ RUBY_EXTERN VALUE rb_xthread_monitor_exit(VALUE);
53
+ RUBY_EXTERN VALUE rb_xthread_monitor_synchronize(VALUE, VALUE (*)(VALUE), VALUE);
54
+ RUBY_EXTERN VALUE rb_xthread_monitor_new_cond(VALUE);
55
+
56
+ RUBY_EXTERN VALUE rb_xthread_monitor_cond_new(VALUE);
57
+ RUBY_EXTERN VALUE rb_xthread_monitor_cond_wait(VALUE, VALUE);
58
+ RUBY_EXTERN VALUE rb_xthread_monitor_cond_wait_while(VALUE);
59
+ RUBY_EXTERN VALUE rb_xthread_monitor_cond_wait_until(VALUE);
60
+ RUBY_EXTERN VALUE rb_xthread_monitor_cond_signal(VALUE);
61
+ RUBY_EXTERN VALUE rb_xthread_monitor_cond_broadcast(VALUE self);
62
+
63
+
64
+
65
+
data/fairy.gemspec CHANGED
@@ -27,15 +27,18 @@ Gem::Specification.new do |s|
27
27
  s.files.concat ["etc/fairy.conf.tmpl"]
28
28
  s.files.concat Dir.glob("bin/{#{s.executables.grep(/.*[a-z]$/).join(",")}}")
29
29
  s.files.concat Dir.glob("bin/subcmd/*[A-Za-z]")
30
- s.files.concat Dir.glob("ext/**/{Makefile,*.rb,*.c}")
30
+ s.files.concat Dir.glob("ext/{*.rb,*.c,*.h}")
31
31
  s.files.concat Dir.glob("doc/*.{rd,html}")
32
32
  s.files.concat Dir.glob("spec/{README,*.rb,run_all.sh}")
33
33
  s.files.concat Dir.glob("sample/*.rb")
34
34
  s.files.concat ["test/testc.rb"]
35
35
  s.files.concat Dir.glob("tools/**/*[a-z]")
36
36
 
37
+ s.add_dependency("xthread", ">= 0.1.4.001")
38
+ s.add_dependency("fiber-mon", ">= 0.2.1")
37
39
  s.add_dependency("DeepConnect", ">= 0.4.06")
38
- s.add_dependency("fiber-mon", ">= 0.1.0")
40
+
41
+ s.extensions = ["ext/extconf.rb"]
39
42
 
40
43
  s.description = <<EOF
41
44
  fairy is a framework for distributed processing in Ruby, originally
data/lib/fairy.rb CHANGED
@@ -4,6 +4,8 @@
4
4
  #
5
5
 
6
6
  require "thread"
7
+ require "xthread"
8
+ require "fiber-mon"
7
9
 
8
10
  require "deep-connect"
9
11
 
@@ -88,6 +90,14 @@ module Fairy
88
90
  Log::info self, "\tfairy version: #{Version}"
89
91
  Log::info(self, "\t[Powered By #{RUBY_DESCRIPTION}]")
90
92
 
93
+
94
+ begin
95
+ require "fairy.so"
96
+ Log::warn self, "\t Load fairy.so"
97
+ rescue LoadError
98
+ Log::warn self, "Can't load fairy.so. Can't use this feature"
99
+ end
100
+
91
101
  @stdout_mutex = Mutex.new
92
102
 
93
103
  if CONF.DEBUG_MONITOR_ON
@@ -203,4 +213,3 @@ require "fairy/client/filter"
203
213
  require "fairy/client/input"
204
214
 
205
215
  require "fairy/client/addins"
206
-
@@ -11,17 +11,30 @@ module Fairy
11
11
 
12
12
  module Interface
13
13
  def group_by(hash_block, opts = nil)
14
+
15
+ klass_name = opts[:group_by] if opts
16
+ klass_name ||= CONF.GROUP_BY
17
+ klass = ::Fairy::const_get(klass_name)
18
+
14
19
  hash_block = BlockSource.new(hash_block)
15
- mod_group_by = GroupBy.new(@fairy, opts, hash_block)
20
+ mod_group_by = klass.new(@fairy, opts, hash_block)
16
21
  mod_group_by.input = self
17
22
  mod_group_by
18
23
  end
24
+
25
+ def xgroup_by(hash_block, opts = nil)
26
+ hash_block = BlockSource.new(hash_block)
27
+ xgroup_by = XGroupBy.new(@fairy, opts, hash_block)
28
+ xgroup_by.input = self
29
+ xgroup_by
30
+ end
19
31
  end
20
32
  Fairy::def_filter_interface Interface
21
33
  ::Fairy::def_post_initialize{post_initialize}
22
34
 
23
35
  UnhandleMethods = [
24
36
  :post_mod_group_by_filter,
37
+ :post_mod_xgroup_by_filter,
25
38
  :post_merge_group_by_filter
26
39
  ]
27
40
  def self.post_initialize
@@ -90,6 +103,49 @@ module Fairy
90
103
  # end
91
104
 
92
105
  end
106
+
107
+ class XGroupBy<GroupBy
108
+ def backend_class_name
109
+ "CXGroupBy"
110
+ end
111
+
112
+ UnhandleMethods = [
113
+ :post_mod_group_by_filter,
114
+ :post_mod_xgroup_by_filter,
115
+ :post_merge_group_by_filter
116
+ ]
117
+ def self.post_initialize
118
+ for interface in ::Fairy::FilterInterfaces
119
+ for m in interface.instance_methods
120
+ m = m.intern if m.kind_of?(String)
121
+ next if UnhandleMethods.include?(m)
122
+
123
+ m = m.id2name
124
+ XGroupBy::module_eval %{
125
+ def #{m}(*argv, &block)
126
+ post_mod_xgroup_by_filter(@block_source, @opts).#{m}(*argv, &block)
127
+ end
128
+ }
129
+ end
130
+ end
131
+ end
132
+ ::Fairy::def_post_initialize{post_initialize}
133
+
134
+ class PostFilter<GroupBy::PostFilter
135
+ module Interface
136
+ def post_mod_xgroup_by_filter(hash_block, opts = nil)
137
+ post_mod_xgroup_by_filter = XGroupBy::PostFilter.new(@fairy, opts, hash_block)
138
+ post_mod_xgroup_by_filter.input = self
139
+ post_mod_xgroup_by_filter
140
+ end
141
+ Fairy::def_filter_interface Interface
142
+ end
143
+
144
+ def backend_class_name
145
+ "CXGroupBy::CPostFilter"
146
+ end
147
+ end
148
+ end
93
149
  end
94
150
 
95
151
 
@@ -190,5 +246,4 @@ Fairy.def_filter(:mod_group_by3) do |fairy, input, block_source, opts = {}|
190
246
  },
191
247
  :postqueuing_policy => {:queuing_class => :OnMemoryQueue}
192
248
  )
193
-
194
249
  end
@@ -2,6 +2,7 @@
2
2
  #
3
3
  # Copyright (C) 2007-2010 Rakuten, Inc.
4
4
  #
5
+ require "xthread"
5
6
 
6
7
  require "fairy/client/io-filter"
7
8
  require "fairy/share/port"
@@ -34,7 +35,7 @@ module Fairy
34
35
  def each(&block)
35
36
  policy = @opts[:prequeuing_policy]
36
37
 
37
- imports = Queue.new
38
+ imports = XThread::Queue.new
38
39
 
39
40
  parent_thread = Thread.current
40
41
 
@@ -6,6 +6,9 @@
6
6
  require "thread"
7
7
  require "forwardable"
8
8
 
9
+ require "xthread"
10
+ require "fiber-mon"
11
+
9
12
  require "deep-connect.rb"
10
13
 
11
14
  require "fairy/version"
@@ -55,20 +58,23 @@ module Fairy
55
58
 
56
59
  @create_processor_mutex = Mutex.new
57
60
 
61
+ # deepspace -> processor_id
62
+ @deepspace2processor_id = {}
63
+
58
64
  # processor -> no of reserve
59
65
  @reserves = {}
60
66
  @reserves_mutex = Mutex.new
61
- @reserves_cv = ConditionVariable.new
67
+ @reserves_cv = XThread::ConditionVariable.new
62
68
 
63
69
  # bjob -> [processor, ...]
64
70
  @bjob2processors = {}
65
71
  @bjob2processors_mutex = Mutex.new
66
- @bjob2processors_cv = ConditionVariable.new
72
+ @bjob2processors_cv = XThread::ConditionVariable.new
67
73
 
68
74
  # processor -> no of active ntasks
69
75
  @no_active_ntasks = {}
70
76
  @no_active_ntasks_mutex = Mutex.new
71
- @no_active_ntasks_cv = ConditionVariable.new
77
+ @no_active_ntasks_cv = XThread::ConditionVariable.new
72
78
 
73
79
  @pool_dict = PoolDictionary.new
74
80
  end
@@ -108,6 +114,13 @@ module Fairy
108
114
  Log::info(self, "\tfairy version: #{Version}")
109
115
  Log::info(self, "\t[Powered by #{RUBY_DESCRIPTION}")
110
116
 
117
+ begin
118
+ require "fairy.so"
119
+ Log::warn self, "\t Load fairy.so"
120
+ rescue LoadError
121
+ Log::warn self, "Can't load fairy.so. Can't use this feature"
122
+ end
123
+
111
124
  @master.register_controller(self)
112
125
 
113
126
  end
@@ -182,6 +195,7 @@ Log::debug(self, "TERMINATE: #2.5.1")
182
195
  Log::debug(self, "TERMINATE: #2.5.1")
183
196
  begin
184
197
  Log::debug(self, "TERMINATE: #2.5.2")
198
+ @deepspace2processor_id[p.deepspace] += "(terminated)"
185
199
  p.node.terminate_processor(p)
186
200
  Log::debug(self, "TERMINATE: #2.5.3")
187
201
  rescue
@@ -274,6 +288,11 @@ Log::debug(self, "TERMINATE: #5")
274
288
  # クライアントがおなくなりになったら, こっちも死ぬよ
275
289
  @master.terminate_controller(self)
276
290
  end
291
+
292
+ if @deepspace2processor_id[deepspace]
293
+ Log::info(self, "CONTROLLER: processor disconected(#{@deepspace2processor_id[deepspace]})")
294
+ @deepspace2processor_id.delete(deepspace)
295
+ end
277
296
  end
278
297
 
279
298
  #
@@ -340,7 +359,9 @@ Log::debug(self, "Processor[#{processor.id}] => #{no_active_ntasks}")
340
359
  def create_processor(node, bjob, &block)
341
360
  @create_processor_mutex.synchronize do
342
361
  processor = node.create_processor
343
- processor.connect_controller(self, CONF)
362
+ proc_id = processor.connect_controller(self, CONF)
363
+ @deepspace2processor_id[processor.deepspace] = proc_id
364
+
344
365
  @reserves_mutex.synchronize do
345
366
  @reserves[processor] = 1
346
367
  end
data/lib/fairy/master.rb CHANGED
@@ -7,6 +7,10 @@ require "thread"
7
7
  require "resolv"
8
8
  require "ipaddr"
9
9
 
10
+ require "xthread"
11
+ require "fiber-mon"
12
+
13
+
10
14
  require "deep-connect"
11
15
  #DeepConnect::Organizer.immutable_classes.push Array
12
16
 
@@ -21,14 +25,14 @@ module Fairy
21
25
 
22
26
  # @clients = {}
23
27
  # @clients_mutex = Mutex.new
24
- # @clients_cv = ConditionVariable.new
28
+ # @clients_cv = XThread::ConditionVariable.new
25
29
 
26
30
  @controller_seq = -1
27
31
  @controller_seq_mutex = Mutex.new
28
32
 
29
33
  @controllers = {}
30
34
  @controllers_mutex = Mutex.new
31
- @controllers_cv = ConditionVariable.new
35
+ @controllers_cv = XThread::ConditionVariable.new
32
36
 
33
37
  # @clientds2controller = {}
34
38
 
@@ -41,7 +45,7 @@ module Fairy
41
45
 
42
46
  @no_of_active_processors = {}
43
47
  @no_of_active_processors_mutex = Mutex.new
44
- @no_of_active_processors_cv = ConditionVariable.new
48
+ @no_of_active_processors_cv = XThread::ConditionVariable.new
45
49
 
46
50
  end
47
51
 
@@ -74,6 +78,13 @@ module Fairy
74
78
  Log.info(self, "Master Service Start")
75
79
  Log::info(self, "\tfairy version: #{Version}")
76
80
  Log::info(self, "\t[Powerd By #{RUBY_DESCRIPTION}]")
81
+
82
+ begin
83
+ require "fairy.so"
84
+ Log::warn self, "\t Load fairy.so"
85
+ rescue LoadError
86
+ Log::warn self, "Can't load fairy.so. Can't use this feature"
87
+ end
77
88
  end
78
89
 
79
90
  def when_disconnected(deepspace, opts)
@@ -327,3 +338,6 @@ Log::debug(self, "LAISURED NODE E:")
327
338
  end
328
339
  end
329
340
  end
341
+
342
+
343
+
@@ -3,6 +3,8 @@
3
3
  # Copyright (C) 2007-2010 Rakuten, Inc.
4
4
  #
5
5
 
6
+ require "xthread"
7
+
6
8
  require "fairy/master/c-io-filter"
7
9
  require "fairy/master/c-inputtable"
8
10
 
@@ -19,10 +21,10 @@ module Fairy
19
21
  # key -> [export, ...]
20
22
  @exports = {}
21
23
  @exports_mutex = Mutex.new
22
- @exports_cv = ConditionVariable.new
24
+ @exports_cv = XThread::ConditionVariable.new
23
25
 
24
26
  # @pre_exports_queue = Queue.new
25
- @exports_queue = Queue.new
27
+ @exports_queue = XThread::Queue.new
26
28
 
27
29
  @each_export_by_thread = nil
28
30
  @each_export_by_thread_mutex = Mutex.new
@@ -6,6 +6,7 @@
6
6
  require "delegate"
7
7
 
8
8
  require "thread"
9
+ require "xthread"
9
10
 
10
11
  require "fairy/master/c-filter"
11
12
  require "fairy/master/c-io-filter"
@@ -22,7 +23,7 @@ module Fairy
22
23
  @others = others
23
24
  @export_node_pairs_queues = nil
24
25
  @export_node_pairs_queues_mutex = Mutex.new
25
- @export_node_pairs_queues_cv = ConditionVariable.new
26
+ @export_node_pairs_queues_cv = XThread::ConditionVariable.new
26
27
 
27
28
  @main_precat = CPreCat.new(controller, opts)
28
29
 
@@ -115,7 +116,7 @@ module Fairy
115
116
 
116
117
  # def start_get_exports
117
118
  # @export_node_pairs_queues = [@input, *@others].collect{|input|
118
- # export_node_pairs = Queue.new
119
+ # export_node_pairs = XThread::Queue.new
119
120
  # Thread.start do
120
121
  # input.each_export do |*export_node_pair|
121
122
  # export_node_pairs.push export_node_pair
@@ -5,6 +5,8 @@
5
5
 
6
6
  require "forwardable"
7
7
 
8
+ require "xthread"
9
+
8
10
  require "deep-connect"
9
11
 
10
12
  require "fairy/master/c-io-filter"
@@ -35,7 +37,7 @@ module Fairy
35
37
 
36
38
  @prefilter_no_nodes = {}
37
39
  @prefilter_no_nodes_mutex = Mutex.new
38
- @prefilter_no_nodes_cv = ConditionVariable.new
40
+ @prefilter_no_nodes_cv = XThread::ConditionVariable.new
39
41
  end
40
42
 
41
43
  attr_reader :other_prefilters
@@ -94,11 +96,11 @@ module Fairy
94
96
  @no = 0
95
97
  @exports = {}
96
98
  @exports_mutex = Mutex.new
97
- # @exports_cv = ConditionVariable.new
99
+ # @exports_cv = XThread::ConditionVariable.new
98
100
 
99
101
  @products = nil
100
102
  @products_mutex = Mutex.new
101
- @products_cv = ConditionVariable.new
103
+ @products_cv = XThread::ConditionVariable.new
102
104
  end
103
105
 
104
106
  def main=(main)
@@ -3,6 +3,8 @@
3
3
  # Copyright (C) 2007-2010 Rakuten, Inc.
4
4
  #
5
5
 
6
+ require "xthread"
7
+
6
8
  module Fairy
7
9
  class CFilter
8
10
  Controller.def_export self
@@ -29,16 +31,16 @@ module Fairy
29
31
 
30
32
  @number_of_nodes = nil
31
33
  # @number_of_nodes_mutex = Mutex.new
32
- # @number_of_nodes_cv = ConditionVariable.new
34
+ # @number_of_nodes_cv = XThread::ConditionVariable.new
33
35
 
34
36
  @nodes = []
35
37
  @nodes_for_next_filters = []
36
38
  @nodes_mutex = Mutex.new
37
- @nodes_cv = ConditionVariable.new
39
+ @nodes_cv = XThread::ConditionVariable.new
38
40
 
39
41
  @nodes_status = {}
40
42
  @nodes_status_mutex = Mutex.new
41
- @nodes_status_cv = ConditionVariable.new
43
+ @nodes_status_cv = XThread::ConditionVariable.new
42
44
 
43
45
  @controller.register_bjob(self)
44
46