fairy 0.6.0
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/LICENSE +674 -0
- data/Makefile +116 -0
- data/README +15 -0
- data/bin/fairy +582 -0
- data/bin/fairy-cat +74 -0
- data/bin/fairy-cp +128 -0
- data/bin/fairy-rm +122 -0
- data/bin/subcmd/controller +41 -0
- data/bin/subcmd/inspector +81 -0
- data/bin/subcmd/master +43 -0
- data/bin/subcmd/node +47 -0
- data/bin/subcmd/processor +54 -0
- data/doc/programming-interface.html +240 -0
- data/doc/programming-interface.rd +300 -0
- data/etc/fairy.conf.tmpl +118 -0
- data/ext/simple_hash/extconf.rb +4 -0
- data/ext/simple_hash/simple_hash.c +42 -0
- data/fairy.gemspec +60 -0
- data/lib/fairy/client/addins.rb +20 -0
- data/lib/fairy/client/barrier.rb +29 -0
- data/lib/fairy/client/basic-group-by.rb +52 -0
- data/lib/fairy/client/cat.rb +41 -0
- data/lib/fairy/client/direct-product.rb +51 -0
- data/lib/fairy/client/equijoin.rb +79 -0
- data/lib/fairy/client/exec.rb +54 -0
- data/lib/fairy/client/filter.rb +62 -0
- data/lib/fairy/client/find.rb +35 -0
- data/lib/fairy/client/group-by.rb +194 -0
- data/lib/fairy/client/here.rb +84 -0
- data/lib/fairy/client/inject.rb +70 -0
- data/lib/fairy/client/input-file.rb +53 -0
- data/lib/fairy/client/input-iota.rb +49 -0
- data/lib/fairy/client/input-local-file.rb +188 -0
- data/lib/fairy/client/input-varray.rb +30 -0
- data/lib/fairy/client/input.rb +42 -0
- data/lib/fairy/client/io-filter.rb +26 -0
- data/lib/fairy/client/junction.rb +31 -0
- data/lib/fairy/client/map.rb +34 -0
- data/lib/fairy/client/merge-group-by.rb +71 -0
- data/lib/fairy/client/output-file.rb +64 -0
- data/lib/fairy/client/output-local-file.rb +60 -0
- data/lib/fairy/client/output-null.rb +47 -0
- data/lib/fairy/client/output-varray.rb +50 -0
- data/lib/fairy/client/output.rb +29 -0
- data/lib/fairy/client/roma-put.rb +62 -0
- data/lib/fairy/client/roma.rb +156 -0
- data/lib/fairy/client/seg-join.rb +61 -0
- data/lib/fairy/client/seg-map.rb +78 -0
- data/lib/fairy/client/seg-shuffle.rb +35 -0
- data/lib/fairy/client/seg-split.rb +27 -0
- data/lib/fairy/client/seg-zip.rb +60 -0
- data/lib/fairy/client/select.rb +38 -0
- data/lib/fairy/client/sort.rb +48 -0
- data/lib/fairy/client/sort18.rb +56 -0
- data/lib/fairy/client/sort19.rb +61 -0
- data/lib/fairy/client/there.rb +47 -0
- data/lib/fairy/client/top_n_into_roma.rb +34 -0
- data/lib/fairy/client/wc.rb +92 -0
- data/lib/fairy/controller.rb +1103 -0
- data/lib/fairy/logger.rb +107 -0
- data/lib/fairy/master/addins.rb +20 -0
- data/lib/fairy/master/atom.rb +17 -0
- data/lib/fairy/master/c-barrier.rb +283 -0
- data/lib/fairy/master/c-basic-group-by.rb +250 -0
- data/lib/fairy/master/c-cat.rb +159 -0
- data/lib/fairy/master/c-direct-product.rb +203 -0
- data/lib/fairy/master/c-exec.rb +68 -0
- data/lib/fairy/master/c-filter.rb +422 -0
- data/lib/fairy/master/c-find.rb +138 -0
- data/lib/fairy/master/c-group-by.rb +64 -0
- data/lib/fairy/master/c-here.rb +80 -0
- data/lib/fairy/master/c-inject.rb +119 -0
- data/lib/fairy/master/c-input-file.rb +46 -0
- data/lib/fairy/master/c-input-iota.rb +66 -0
- data/lib/fairy/master/c-input-local-file.rb +117 -0
- data/lib/fairy/master/c-input-varray.rb +53 -0
- data/lib/fairy/master/c-input.rb +24 -0
- data/lib/fairy/master/c-inputtable.rb +31 -0
- data/lib/fairy/master/c-inputtable18.rb +36 -0
- data/lib/fairy/master/c-inputtable19.rb +35 -0
- data/lib/fairy/master/c-io-filter.rb +28 -0
- data/lib/fairy/master/c-junction.rb +54 -0
- data/lib/fairy/master/c-map.rb +27 -0
- data/lib/fairy/master/c-merge-group-by.rb +241 -0
- data/lib/fairy/master/c-output-file.rb +84 -0
- data/lib/fairy/master/c-output-local-file.rb +19 -0
- data/lib/fairy/master/c-output-null.rb +45 -0
- data/lib/fairy/master/c-output-varray.rb +57 -0
- data/lib/fairy/master/c-output.rb +20 -0
- data/lib/fairy/master/c-seg-join.rb +141 -0
- data/lib/fairy/master/c-seg-map.rb +26 -0
- data/lib/fairy/master/c-seg-shuffle.rb +87 -0
- data/lib/fairy/master/c-seg-split.rb +110 -0
- data/lib/fairy/master/c-seg-zip.rb +132 -0
- data/lib/fairy/master/c-select.rb +27 -0
- data/lib/fairy/master/c-sort.rb +108 -0
- data/lib/fairy/master/c-there.rb +57 -0
- data/lib/fairy/master/c-wc.rb +232 -0
- data/lib/fairy/master/job-interpriter.rb +19 -0
- data/lib/fairy/master/scheduler.rb +24 -0
- data/lib/fairy/master.rb +329 -0
- data/lib/fairy/node/addins.rb +19 -0
- data/lib/fairy/node/p-barrier.rb +95 -0
- data/lib/fairy/node/p-basic-group-by.rb +252 -0
- data/lib/fairy/node/p-direct-product.rb +153 -0
- data/lib/fairy/node/p-exec.rb +30 -0
- data/lib/fairy/node/p-filter.rb +363 -0
- data/lib/fairy/node/p-find.rb +111 -0
- data/lib/fairy/node/p-group-by.rb +1534 -0
- data/lib/fairy/node/p-here.rb +21 -0
- data/lib/fairy/node/p-identity.rb +24 -0
- data/lib/fairy/node/p-inject.rb +127 -0
- data/lib/fairy/node/p-input-file.rb +108 -0
- data/lib/fairy/node/p-input-iota.rb +39 -0
- data/lib/fairy/node/p-input-local-file.rb +61 -0
- data/lib/fairy/node/p-input-varray.rb +26 -0
- data/lib/fairy/node/p-io-filter.rb +28 -0
- data/lib/fairy/node/p-map.rb +40 -0
- data/lib/fairy/node/p-merger-group-by.rb +48 -0
- data/lib/fairy/node/p-output-file.rb +104 -0
- data/lib/fairy/node/p-output-local-file.rb +14 -0
- data/lib/fairy/node/p-output-null.rb +32 -0
- data/lib/fairy/node/p-output-varray.rb +41 -0
- data/lib/fairy/node/p-seg-join.rb +82 -0
- data/lib/fairy/node/p-seg-map.rb +34 -0
- data/lib/fairy/node/p-seg-split.rb +61 -0
- data/lib/fairy/node/p-seg-zip.rb +79 -0
- data/lib/fairy/node/p-select.rb +40 -0
- data/lib/fairy/node/p-single-exportable.rb +90 -0
- data/lib/fairy/node/p-sort.rb +195 -0
- data/lib/fairy/node/p-task.rb +113 -0
- data/lib/fairy/node/p-there.rb +44 -0
- data/lib/fairy/node/p-wc.rb +266 -0
- data/lib/fairy/node.rb +187 -0
- data/lib/fairy/processor.rb +510 -0
- data/lib/fairy/share/base-app.rb +114 -0
- data/lib/fairy/share/block-source.rb +234 -0
- data/lib/fairy/share/conf.rb +396 -0
- data/lib/fairy/share/debug.rb +21 -0
- data/lib/fairy/share/encoding.rb +17 -0
- data/lib/fairy/share/fast-tempfile.rb +93 -0
- data/lib/fairy/share/file-place.rb +176 -0
- data/lib/fairy/share/hash-1.rb +20 -0
- data/lib/fairy/share/hash-md5.rb +28 -0
- data/lib/fairy/share/hash-murmur.rb +69 -0
- data/lib/fairy/share/hash-rb18.rb +20 -0
- data/lib/fairy/share/hash-simple-hash.rb +28 -0
- data/lib/fairy/share/inspector.rb +16 -0
- data/lib/fairy/share/lc/exceptions.rb +82 -0
- data/lib/fairy/share/lc/ja/exceptions.rb +81 -0
- data/lib/fairy/share/locale.rb +17 -0
- data/lib/fairy/share/log.rb +215 -0
- data/lib/fairy/share/pool-dictionary.rb +53 -0
- data/lib/fairy/share/port-marshaled-queue.rb +347 -0
- data/lib/fairy/share/port.rb +1697 -0
- data/lib/fairy/share/reference.rb +45 -0
- data/lib/fairy/share/stdout.rb +56 -0
- data/lib/fairy/share/tr.rb +16 -0
- data/lib/fairy/share/varray.rb +147 -0
- data/lib/fairy/share/vfile.rb +183 -0
- data/lib/fairy/version.rb +8 -0
- data/lib/fairy.rb +206 -0
- data/sample/grep.rb +46 -0
- data/sample/ping.rb +19 -0
- data/sample/sort.rb +102 -0
- data/sample/wordcount.rb +61 -0
- data/spec/README +12 -0
- data/spec/fairy1_spec.rb +31 -0
- data/spec/fairy2_spec.rb +42 -0
- data/spec/fairy3_spec.rb +126 -0
- data/spec/fairy4_spec.rb +63 -0
- data/spec/fairy5_spec.rb +45 -0
- data/spec/fairy6_spec.rb +52 -0
- data/spec/fairy7_spec.rb +58 -0
- data/spec/fairy8_spec.rb +48 -0
- data/spec/mkdat.rb +148 -0
- data/spec/run_all.sh +65 -0
- data/test/testc.rb +7111 -0
- data/tools/cap_recipe/Capfile +144 -0
- data/tools/cap_recipe/cluster.yml.sample +14 -0
- data/tools/fairy_perf_graph.rb +444 -0
- data/tools/git-tag +44 -0
- data/tools/log-analysis.rb +62 -0
- data/tools/svn-ls-diff +38 -0
- data/tools/svn-tags +37 -0
- metadata +298 -0
data/lib/fairy/logger.rb
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2007-2010 Rakuten, Inc.
|
|
4
|
+
#
|
|
5
|
+
|
|
6
|
+
module Fairy
|
|
7
|
+
class Logger
|
|
8
|
+
|
|
9
|
+
LOG_FILE = CONF.LOG_FILE
|
|
10
|
+
|
|
11
|
+
FLUSH_INTERVAL = CONF.LOG_FLUSH_INTERVAL
|
|
12
|
+
MARK_INTERVAL = CONF.LOG_MARK_INTERVAL
|
|
13
|
+
LOG_ROTATE_INTERVAL = CONF.LOG_ROTATE_INTERVAL
|
|
14
|
+
|
|
15
|
+
def initialize(path = LOG_FILE)
|
|
16
|
+
@log_file_path = path
|
|
17
|
+
|
|
18
|
+
open_log
|
|
19
|
+
|
|
20
|
+
@mutex = Mutex.new
|
|
21
|
+
@buffered = false
|
|
22
|
+
|
|
23
|
+
start_flusher
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def open_log
|
|
27
|
+
begin
|
|
28
|
+
@log_out = File.open(@log_file_path, "a+")
|
|
29
|
+
rescue Errno::ENOENT
|
|
30
|
+
ERR::Fail ERR::NoLogDir, @log_file_path
|
|
31
|
+
rescue
|
|
32
|
+
raise
|
|
33
|
+
end
|
|
34
|
+
@log_open_time = Time.now
|
|
35
|
+
@log_out.puts @log_open_time.strftime("%Y/%m/%d %H:%M:%S -- LOGGER START --")
|
|
36
|
+
@log_out.flush
|
|
37
|
+
|
|
38
|
+
@marked_time = @log_open_time
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def start_flusher
|
|
42
|
+
Thread.start do
|
|
43
|
+
loop do
|
|
44
|
+
sleep FLUSH_INTERVAL
|
|
45
|
+
@mutex.synchronize do
|
|
46
|
+
if @buffered
|
|
47
|
+
@log_out.flush
|
|
48
|
+
@buffered = false
|
|
49
|
+
end
|
|
50
|
+
now = Time.now
|
|
51
|
+
if MARK_INTERVAL && now - @marked_time > MARK_INTERVAL
|
|
52
|
+
@log_out.puts now.strftime("%Y/%m/%d %H:%M:%S -- MARK --")
|
|
53
|
+
@log_out.flush
|
|
54
|
+
@marked_time = now
|
|
55
|
+
end
|
|
56
|
+
if LOG_ROTATE_INTERVAL && now - @log_open_time > LOG_ROTATE_INTERVAL
|
|
57
|
+
log_rotate
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def message(message)
|
|
65
|
+
@mutex.synchronize do
|
|
66
|
+
@log_out.puts message
|
|
67
|
+
@buffered = true
|
|
68
|
+
end
|
|
69
|
+
nil
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def messages(messages)
|
|
73
|
+
@mutex.synchronize do
|
|
74
|
+
messages.each do |m|
|
|
75
|
+
@log_out.puts m
|
|
76
|
+
end
|
|
77
|
+
@buffered = true
|
|
78
|
+
end
|
|
79
|
+
nil
|
|
80
|
+
end
|
|
81
|
+
DeepConnect.def_method_spec(self, "REF messages(DVAL)")
|
|
82
|
+
|
|
83
|
+
def log_rotate
|
|
84
|
+
@log_out.close
|
|
85
|
+
log_back = "#{@log_file_path}.BAK-$$"
|
|
86
|
+
File.rename(@log_file_path, log_back)
|
|
87
|
+
open_log
|
|
88
|
+
|
|
89
|
+
Thread.start do
|
|
90
|
+
files = Dir.glob("#{@log_file_path}.[0-9]*").sort{|f1, f2| f2 <=> f1}
|
|
91
|
+
while files.size >= CONF.LOG_ROTATE_N
|
|
92
|
+
File.unlink(files.shift)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
files.each do |f|
|
|
96
|
+
fn = f.sub(/\.[0-9]+/){|n| n.succ}
|
|
97
|
+
File.rename(f, fn)
|
|
98
|
+
if /.*\.gz$/ !~ fn
|
|
99
|
+
system("gzip #{fn}")
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
File.rename(log_back, "#{@log_file_path}.0")
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2007-2010 Rakuten, Inc.
|
|
4
|
+
#
|
|
5
|
+
|
|
6
|
+
bjob_dir = File.dirname(__FILE__)
|
|
7
|
+
subdir = File.basename(File.dirname(bjob_dir))
|
|
8
|
+
bjob_name = File.basename(bjob_dir)
|
|
9
|
+
for bjob in Dir.glob("#{bjob_dir}/*.rb")
|
|
10
|
+
base = File.basename(bjob)
|
|
11
|
+
case base
|
|
12
|
+
when /18.rb$/
|
|
13
|
+
next if RUBY_VERSION >= "1.9.0"
|
|
14
|
+
when /19.rb$/
|
|
15
|
+
next unless RUBY_VERSION >= "1.9.0"
|
|
16
|
+
end
|
|
17
|
+
require [subdir, bjob_name, base].join("/")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2007-2010 Rakuten, Inc.
|
|
4
|
+
#
|
|
5
|
+
|
|
6
|
+
require "forwardable"
|
|
7
|
+
|
|
8
|
+
require "deep-connect"
|
|
9
|
+
|
|
10
|
+
require "fairy/master/c-filter"
|
|
11
|
+
require "fairy/master/c-inputtable"
|
|
12
|
+
require "fairy/master/c-io-filter"
|
|
13
|
+
|
|
14
|
+
require "fairy/share/block-source"
|
|
15
|
+
|
|
16
|
+
module Fairy
|
|
17
|
+
class CBarrier<CIOFilter
|
|
18
|
+
extend Forwardable
|
|
19
|
+
|
|
20
|
+
Controller.def_export self
|
|
21
|
+
|
|
22
|
+
# include BInputtable
|
|
23
|
+
|
|
24
|
+
DeepConnect.def_single_method_spec(self, "REF new(REF, VAL)")
|
|
25
|
+
|
|
26
|
+
def initialize(controller, opts)
|
|
27
|
+
super
|
|
28
|
+
for k, val in opts.dup
|
|
29
|
+
case k
|
|
30
|
+
when :mode
|
|
31
|
+
@mode = CBarrierMode.create(self, val, opts)
|
|
32
|
+
when :cond
|
|
33
|
+
@cond = CBarrierCond.create(self, val, opts)
|
|
34
|
+
when :buffer
|
|
35
|
+
@buffer = CBarrierBuffer.create(self, val, opts)
|
|
36
|
+
else
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def each_assigned_filter(&block)
|
|
42
|
+
@mode.wait_exportable
|
|
43
|
+
@buffer.each_assigned_filter(&block)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def_delegator :@mode, :wait_export
|
|
47
|
+
|
|
48
|
+
def_delegator :@cond, :wait_cond
|
|
49
|
+
|
|
50
|
+
def_delegator :@buffer, :input=
|
|
51
|
+
def_delegator :@buffer, :output=
|
|
52
|
+
|
|
53
|
+
def_delegator :@buffer, :node_arrived?
|
|
54
|
+
def_delegator :@buffer, :data_arrived?
|
|
55
|
+
def_delegator :@buffer, :all_data_imported?
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
module Factory
|
|
59
|
+
def self.extended(mod)
|
|
60
|
+
mod.init_fact
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def init_fact
|
|
64
|
+
@ModeName2Class = {}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def create(bbarrier, mode, *opts)
|
|
68
|
+
klass = @ModeName2Class[mode]
|
|
69
|
+
ERR::Raise ERR::NoSuchMode, mode unless klass
|
|
70
|
+
|
|
71
|
+
mode = klass.new(bbarrier, mode, *opts)
|
|
72
|
+
mode
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def register_mode(mode, klass)
|
|
76
|
+
@ModeName2Class[mode] = klass
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
module Mode
|
|
81
|
+
def initialize(bbarrier, mode, *opts)
|
|
82
|
+
@bbarrier = bbarrier
|
|
83
|
+
@mode = mode
|
|
84
|
+
@opts = opts.last
|
|
85
|
+
# Log::debug self, self.class.superclass.name
|
|
86
|
+
begin
|
|
87
|
+
super(*opts)
|
|
88
|
+
rescue
|
|
89
|
+
# for ruby 1.9.1
|
|
90
|
+
super()
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
#
|
|
96
|
+
class CBarrierMode
|
|
97
|
+
extend Factory
|
|
98
|
+
include Mode
|
|
99
|
+
|
|
100
|
+
def initialize(bbarrier, mode, *opts)
|
|
101
|
+
super
|
|
102
|
+
@opts = opts
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
class CBarrierNodeCreationMode<CBarrierMode
|
|
108
|
+
CBarrierMode.register_mode(:NODE_CREATION, self)
|
|
109
|
+
|
|
110
|
+
def wait_exportable
|
|
111
|
+
@bbarrier.wait_cond
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def wait_export
|
|
115
|
+
true
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
class CBarrierStreamMode<CBarrierMode
|
|
121
|
+
CBarrierMode.register_mode(:STREAM, self)
|
|
122
|
+
|
|
123
|
+
def wait_exportable
|
|
124
|
+
true
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def wait_export
|
|
128
|
+
@bbarrier.wait_cond
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
#
|
|
134
|
+
class CBarrierCond
|
|
135
|
+
extend Factory
|
|
136
|
+
include Mode
|
|
137
|
+
|
|
138
|
+
def self.create(bbarrier, mode, opts=nil)
|
|
139
|
+
if mode.kind_of?(BlockSource)
|
|
140
|
+
opts[:BLOCK_SOURCE] = mode
|
|
141
|
+
super(bbarrier, :BLOCK_COND, opts)
|
|
142
|
+
else
|
|
143
|
+
super(bbarrier, mode, opts)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def wait_cond
|
|
148
|
+
ERR::Raise ERR::NoImpliment, "wait_cond"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
class CBarrierNodeArrivedCond<CBarrierCond
|
|
154
|
+
CBarrierCond.register_mode(:NODE_ARRIVED, self)
|
|
155
|
+
|
|
156
|
+
def wait_cond
|
|
157
|
+
@bbarrier.node_arrived?
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
class CBarrierDataArrivedCond<CBarrierCond
|
|
163
|
+
CBarrierCond.register_mode(:DATA_ARRIVED, self)
|
|
164
|
+
|
|
165
|
+
def wait_cond
|
|
166
|
+
@bbarrier.data_arrived?
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
class CBarrierAllDataCond<CBarrierCond
|
|
172
|
+
CBarrierCond.register_mode(:ALL_DATA, self)
|
|
173
|
+
|
|
174
|
+
def wait_cond
|
|
175
|
+
@bbarrier.all_data_imported?
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
class CBarrierBlockCond<CBarrierCond
|
|
180
|
+
CBarrierCond.register_mode(:BLOCK_COND, self)
|
|
181
|
+
|
|
182
|
+
def initialize(bbarrier, mode, opts)
|
|
183
|
+
super(bbarrier, mode, opts)
|
|
184
|
+
|
|
185
|
+
if @opts[:BEGIN]
|
|
186
|
+
bs = BScript.new(@opts[:BEGIN],
|
|
187
|
+
@bbarrier.instance_eval{@context},
|
|
188
|
+
@bbarrier)
|
|
189
|
+
bs.evaluate
|
|
190
|
+
end
|
|
191
|
+
@block_source = @opts[:BLOCK_SOURCE]
|
|
192
|
+
@block = BBlock.new(@block_source,
|
|
193
|
+
@bbarrier.instance_eval{@context},
|
|
194
|
+
@bbarrier)
|
|
195
|
+
# @opts[:END] は未サポート
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def wait_cond
|
|
199
|
+
@block.call
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
#
|
|
204
|
+
class CBarrierBuffer<CIOFilter
|
|
205
|
+
extend Factory
|
|
206
|
+
include Mode
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
class CBarrierMemoryBuffer<CBarrierBuffer
|
|
210
|
+
CBarrierBuffer.register_mode(:MEMORY, self)
|
|
211
|
+
|
|
212
|
+
def initialize(bbarrier, mode, opts=nil)
|
|
213
|
+
super(bbarrier, mode, bbarrier.instance_eval{@controller}, opts)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def node_arrived?
|
|
217
|
+
number_of_nodes
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def data_arrived?
|
|
221
|
+
@nodes_status_mutex.synchronize do
|
|
222
|
+
while !all_node_data_arrived?
|
|
223
|
+
@nodes_status_cv.wait(@nodes_status_mutex)
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
true
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def all_data_imported?
|
|
230
|
+
@nodes_status_mutex.synchronize do
|
|
231
|
+
while !all_node_data_imported?
|
|
232
|
+
@nodes_status_cv.wait(@nodes_status_mutex)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
true
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def node_class_name
|
|
239
|
+
"PBarrierMemoryBuffer"
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def wait_export
|
|
243
|
+
@bbarrier.wait_export
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def all_node_data_arrived?
|
|
247
|
+
return false unless @number_of_nodes
|
|
248
|
+
|
|
249
|
+
data_arrived = true
|
|
250
|
+
each_node(:exist_only) do |node|
|
|
251
|
+
st = @nodes_status[node]
|
|
252
|
+
data_arrived &&= [:ST_ACTIVATE, :ST_ALL_IMPORTED, :ST_FINISH, :ST_EXPORT_FINISH, :ST_WAIT_EXPORT_FINISH].include?(st)
|
|
253
|
+
end
|
|
254
|
+
data_arrived
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def all_node_data_imported?
|
|
258
|
+
return false unless @number_of_nodes
|
|
259
|
+
|
|
260
|
+
all_data_imported = true
|
|
261
|
+
each_node(:exist_only) do |node|
|
|
262
|
+
st = @nodes_status[node]
|
|
263
|
+
s = [:ST_ALL_IMPORTED, :ST_FINISH, :ST_EXPORT_FINISH, :ST_WAIT_EXPORT_FINISH].include?(st)
|
|
264
|
+
all_data_imported &&= [:ST_ALL_IMPORTED, :ST_FINISH, :ST_EXPORT_FINISH, :ST_WAIT_EXPORT_FINISH].include?(st)
|
|
265
|
+
end
|
|
266
|
+
all_data_imported
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
class CBarrierFileBuffer<CBarrierBuffer
|
|
272
|
+
CBarrierBuffer.register_mode(:FILE, self)
|
|
273
|
+
|
|
274
|
+
def node_class_name
|
|
275
|
+
"PBarrier::PBarrierFileBuffer"
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2007-2010 Rakuten, Inc.
|
|
4
|
+
#
|
|
5
|
+
|
|
6
|
+
require "fairy/master/c-io-filter"
|
|
7
|
+
require "fairy/master/c-inputtable"
|
|
8
|
+
|
|
9
|
+
module Fairy
|
|
10
|
+
class CBasicGroupBy<CIOFilter
|
|
11
|
+
Controller.def_export self
|
|
12
|
+
|
|
13
|
+
def initialize(controller, opts, block_source)
|
|
14
|
+
super
|
|
15
|
+
@block_source = block_source
|
|
16
|
+
|
|
17
|
+
@no_of_exports = 0
|
|
18
|
+
|
|
19
|
+
# key -> [export, ...]
|
|
20
|
+
@exports = {}
|
|
21
|
+
@exports_mutex = Mutex.new
|
|
22
|
+
@exports_cv = ConditionVariable.new
|
|
23
|
+
|
|
24
|
+
# @pre_exports_queue = Queue.new
|
|
25
|
+
@exports_queue = Queue.new
|
|
26
|
+
|
|
27
|
+
@each_export_by_thread = nil
|
|
28
|
+
@each_export_by_thread_mutex = Mutex.new
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def start_create_nodes
|
|
32
|
+
super
|
|
33
|
+
|
|
34
|
+
start_watch_all_node_imported
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# def each_export(&block)
|
|
38
|
+
# while pair = @exports_queue.pop
|
|
39
|
+
# block.call pair
|
|
40
|
+
# end
|
|
41
|
+
# end
|
|
42
|
+
|
|
43
|
+
# def next_filter(mapper)
|
|
44
|
+
# ret = super
|
|
45
|
+
# unless ret
|
|
46
|
+
# @each_export_by_thread_mutex.synchronize do
|
|
47
|
+
# @each_export_by_thread.join if @each_export_by_thread
|
|
48
|
+
# end
|
|
49
|
+
# end
|
|
50
|
+
# ret
|
|
51
|
+
# end
|
|
52
|
+
|
|
53
|
+
def each_assigned_filter(&block)
|
|
54
|
+
super
|
|
55
|
+
|
|
56
|
+
@each_export_by_thread_mutex.synchronize do
|
|
57
|
+
@each_export_by_thread.join if @each_export_by_thread
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# def each_export_by(njob, mapper, &block)
|
|
62
|
+
# return if @each_export_by_thread
|
|
63
|
+
|
|
64
|
+
# begin
|
|
65
|
+
# while pair = @exports_queue.pop
|
|
66
|
+
# exp, njob = pair
|
|
67
|
+
# Log::debug(self, "EXPORT_BY, #{exp.key}")
|
|
68
|
+
# block.call exp
|
|
69
|
+
# end
|
|
70
|
+
# rescue
|
|
71
|
+
# Log::fatal_exception
|
|
72
|
+
# end
|
|
73
|
+
# @each_export_by_thread = true
|
|
74
|
+
# end
|
|
75
|
+
|
|
76
|
+
def each_export_by(njob, mapper, &block)
|
|
77
|
+
@each_export_by_thread_mutex.synchronize do
|
|
78
|
+
return if @each_export_by_thread
|
|
79
|
+
|
|
80
|
+
@each_export_by_thread = Thread.start{
|
|
81
|
+
# すべての njob がそろうまで待つ
|
|
82
|
+
# 後段が先にスケジュールされてデッドロックするのを避けるため.
|
|
83
|
+
number_of_nodes
|
|
84
|
+
|
|
85
|
+
begin
|
|
86
|
+
while pair = @exports_queue.pop
|
|
87
|
+
exp, njob = pair
|
|
88
|
+
Log::debug(self, "EXPORT_BY, #{exp.key}")
|
|
89
|
+
block.call exp
|
|
90
|
+
|
|
91
|
+
@exports_mutex.synchronize do
|
|
92
|
+
if @exports[exp.key].first == exp
|
|
93
|
+
@exports[exp.key][1..-1].each do |e|
|
|
94
|
+
e.output = exp.output
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
rescue
|
|
100
|
+
Log::fatal_exception
|
|
101
|
+
raise
|
|
102
|
+
end
|
|
103
|
+
}
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def bind_export(exp, imp)
|
|
108
|
+
# do nothing
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def add_exports(key, export, njob)
|
|
112
|
+
@exports_mutex.synchronize do
|
|
113
|
+
if exports = @exports[key]
|
|
114
|
+
export.output = exports.first.output if exports.first.output?
|
|
115
|
+
export.no = exports.first.no
|
|
116
|
+
exports.push export
|
|
117
|
+
else
|
|
118
|
+
export.no = @no_of_exports
|
|
119
|
+
@no_of_exports += 1
|
|
120
|
+
@exports[key] = [export]
|
|
121
|
+
@exports_queue.push [export, njob]
|
|
122
|
+
# @pre_exports_queue.push [export, njob]
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def update_exports(key, export, njob)
|
|
128
|
+
add_exports(key, export, njob)
|
|
129
|
+
nil
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def node_class_name
|
|
133
|
+
"PBasicGroupBy"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def njob_creation_params
|
|
137
|
+
[@block_source]
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def start_watch_all_node_imported
|
|
141
|
+
Thread.start do
|
|
142
|
+
# すべての njob がそろうまで待つ
|
|
143
|
+
# 後段が先にスケジュールされてデッドロックするのを避けるため.
|
|
144
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: S")
|
|
145
|
+
number_of_nodes
|
|
146
|
+
|
|
147
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 1")
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 2")
|
|
151
|
+
# すべての exports がそろうまで待つ
|
|
152
|
+
@nodes_status_mutex.synchronize do
|
|
153
|
+
while !all_node_imported?
|
|
154
|
+
@nodes_status_cv.wait(@nodes_status_mutex)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
@exports_queue.push nil
|
|
158
|
+
|
|
159
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 4")
|
|
160
|
+
for key, exports in @exports
|
|
161
|
+
exports.first.output_no_import = exports.size
|
|
162
|
+
end
|
|
163
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: E")
|
|
164
|
+
end
|
|
165
|
+
nil
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def start_watch_all_node_imported_ORG
|
|
169
|
+
Thread.start do
|
|
170
|
+
# すべての njob がそろうまで待つ
|
|
171
|
+
# 後段が先にスケジュールされてデッドロックするのを避けるため.
|
|
172
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: S")
|
|
173
|
+
number_of_nodes
|
|
174
|
+
|
|
175
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 1")
|
|
176
|
+
# すでに存在するexportsを下流に送る
|
|
177
|
+
@exports_mutex.synchronize do
|
|
178
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 1.1")
|
|
179
|
+
@pre_exports_queue.push nil
|
|
180
|
+
while pair = @pre_exports_queue.pop
|
|
181
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 1.2: EXP.NO: #{pair[0].no}")
|
|
182
|
+
@exports_queue.push pair
|
|
183
|
+
end
|
|
184
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 1.3")
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 2")
|
|
188
|
+
# すべての exports がそろうまで待つ
|
|
189
|
+
@nodes_status_mutex.synchronize do
|
|
190
|
+
while !all_node_imported?
|
|
191
|
+
@nodes_status_cv.wait(@nodes_status_mutex)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 3")
|
|
196
|
+
# 残りのexportsを下流に送る
|
|
197
|
+
@pre_exports_queue.push nil
|
|
198
|
+
while pair = @pre_exports_queue.pop
|
|
199
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 3.1: EXP.NO: #{pair[0].no}")
|
|
200
|
+
@exports_queue.push pair
|
|
201
|
+
end
|
|
202
|
+
@exports_queue.push nil
|
|
203
|
+
|
|
204
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 4")
|
|
205
|
+
#Log::debug(self, "START: setting for EXPOTRS.SIZE")
|
|
206
|
+
for key, exports in @exports
|
|
207
|
+
# exports[1..-1].each do |exp|
|
|
208
|
+
# exp.output=exports.first.output
|
|
209
|
+
# end
|
|
210
|
+
|
|
211
|
+
#Log::debug(self, "EXPOTRS.SIZE=#{exports.size}")
|
|
212
|
+
exports.first.output_no_import = exports.size
|
|
213
|
+
end
|
|
214
|
+
#Log::debug(self, "END: setting for EXPOTRS.SIZE")
|
|
215
|
+
Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: E")
|
|
216
|
+
end
|
|
217
|
+
nil
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def all_node_arrived?
|
|
221
|
+
@nodes_mutex.synchronize{@number_of_nodes}
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def all_node_imported?
|
|
225
|
+
# すべてのnjobがそろったか?
|
|
226
|
+
return false unless @nodes_mutex.synchronize{@number_of_nodes}
|
|
227
|
+
|
|
228
|
+
each_node(:exist_only) do |node|
|
|
229
|
+
st = @nodes_status[node]
|
|
230
|
+
# こちらはNG: outputが設定されていないとまずい.
|
|
231
|
+
# すべてのnodeがそろったとしてもすべてのexportがそろっているとは限らない
|
|
232
|
+
# unless [:ST_FINISH, :ST_EXPORT_FINISH, :ST_WAIT_EXPORT_FINISH, :ST_ALL_IMPORTED].include?(st)
|
|
233
|
+
unless [:ST_FINISH, :ST_EXPORT_FINISH, :ST_WAIT_EXPORT_FINISH].include?(st)
|
|
234
|
+
return false
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
true
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
class CBasicMGroupBy<CBasicGroupBy
|
|
242
|
+
Controller.def_export self
|
|
243
|
+
|
|
244
|
+
def node_class_name
|
|
245
|
+
"PBasicMGroupBy"
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
end
|