map_reduce 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -24,4 +24,4 @@ require File.expand_path("../map_reduce/reduce_log", __FILE__)
24
24
  require File.expand_path("../map_reduce/socket/master", __FILE__)
25
25
  require File.expand_path("../map_reduce/master", __FILE__)
26
26
  require File.expand_path("../map_reduce/mapper", __FILE__)
27
- require File.expand_path("../map_reduce/reducer", __FILE__)
27
+ require File.expand_path("../map_reduce/reducer", __FILE__)
@@ -40,9 +40,7 @@ module MapReduce
40
40
 
41
41
  def log_file
42
42
  @log_file ||= begin
43
- begin
44
- fn = File.join(@log_folder, "mapper.log")
45
- end while File.exist?(fn)
43
+ fn = File.join(@log_folder, "mapper.log")
46
44
  FileUtils.mkdir_p(@log_folder)
47
45
  File.open(fn, "a")
48
46
  end
@@ -4,13 +4,26 @@ module MapReduce
4
4
  @masters = opts[:masters] || [::MapReduce::DEFAULT_SOCKET]
5
5
  @connection_type = opts[:type] || :em
6
6
  @task_name = opts[:task]
7
+ @disconnected = {}
7
8
  end
8
9
 
9
10
  def emit(key, value, &blk)
10
11
  raise MapReduce::Exceptions::BlankKey, "Key can't be nil" if key.nil?
11
12
 
12
13
  sock = pick_master(key)
13
- sock.send_request(["map", key, value, @task_name], &blk)
14
+ sock.send_request(["map", key, value, @task_name]) do |res|
15
+ if res
16
+ @disconnected.delete(sock) if @disconnected[sock]
17
+ if blk
18
+ blk.call(res)
19
+ else
20
+ return res
21
+ end
22
+ else
23
+ @disconnected[sock] = true
24
+ emit(key, value, &blk)
25
+ end
26
+ end
14
27
  end
15
28
  alias :map :emit
16
29
 
@@ -50,7 +63,13 @@ module MapReduce
50
63
 
51
64
  def pick_master(key)
52
65
  num = Digest::MD5.hexdigest(key.to_s).to_i(16) % sockets.size
53
- sockets[num]
66
+ sock = sockets[num]
67
+ # LOL :)
68
+ if @disconnected[sock] && rand(10) != 0
69
+ pick_master(key.chars.to_a.shuffle.join)
70
+ else
71
+ sock
72
+ end
54
73
  end
55
74
 
56
75
  def sockets
@@ -56,7 +56,7 @@ module MapReduce
56
56
  end
57
57
 
58
58
  def sort(fn)
59
- `sort #{fn} -o #{fn}`
59
+ `sort #{fn} -o #{fn} -k1nr`
60
60
  end
61
61
  end
62
62
  end
@@ -1,5 +1,7 @@
1
1
  module MapReduce
2
2
  class Reducer
3
+ TIMEOUT = 0.1
4
+
3
5
  def initialize(opts = {})
4
6
  @masters = opts[:masters] || [::MapReduce::DEFAULT_SOCKET]
5
7
  @connection_type = opts[:type] || :em
@@ -2,9 +2,17 @@ module EM::Protocols::Zmq2
2
2
  class ReqFiber < EM::Protocols::Zmq2::ReqCb
3
3
  def send_request(data, &blk)
4
4
  fib = Fiber.current
5
- super(data) do |message|
5
+ timer = nil
6
+ request_id = super(data) do |message|
7
+ EM.cancel_timer(timer)
6
8
  fib.resume(message)
7
9
  end
10
+ if request_id
11
+ timer = EM.add_timer(1) {
12
+ MapReduce.logger.info("TIMEOUT")
13
+ cancel_request(request_id)
14
+ }
15
+ end
8
16
  if block_given?
9
17
  blk.call Fiber.yield
10
18
  else
@@ -1,3 +1,3 @@
1
1
  module MapReduce
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -137,6 +137,28 @@ describe "MapReduce stack" do
137
137
  EM.stop
138
138
  end
139
139
  end
140
+
141
+ it "should use one master" do
142
+ EM.synchrony do
143
+ # MapReduce::Reducer.const_set :TIMEOUT, 0.1
144
+ Process.kill "INT", @pid2
145
+ @mapper = MapReduce::Mapper.new type: :sync, task: "Fruits", masters: ["tcp://127.0.0.1:15555", "tcp://127.0.0.1:15556"]
146
+ @reducer = MapReduce::Reducer.new type: :sync, task: "Fruits", masters: ["tcp://127.0.0.1:15555", "tcp://127.0.0.1:15556"]
147
+ [["Peter", "Apple"], ["Andrew", "Peach"], ["Mary", "Plum"], ["Peter", "Lemon"], ["Andrew", "Orange"]].each do |a|
148
+ res = @mapper.map(*a)
149
+ res.must_equal ["ok"]
150
+ end
151
+ data = {}
152
+ @reducer.reduce do |k, values|
153
+ data[k] = values
154
+ end
155
+ data.size.must_equal 3
156
+ data["Peter"].sort.must_equal ["Apple", "Lemon"].sort
157
+ data["Andrew"].sort.must_equal ["Peach", "Orange"].sort
158
+ data["Mary"].must_equal ["Plum"]
159
+ EM.stop
160
+ end
161
+ end
140
162
  end
141
163
  end
142
164
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: map_reduce
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-06 00:00:00.000000000 Z
12
+ date: 2013-07-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -117,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
117
117
  version: '0'
118
118
  segments:
119
119
  - 0
120
- hash: 2639793831628664557
120
+ hash: -2358155464795184173
121
121
  required_rubygems_version: !ruby/object:Gem::Requirement
122
122
  none: false
123
123
  requirements:
@@ -126,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
126
  version: '0'
127
127
  segments:
128
128
  - 0
129
- hash: 2639793831628664557
129
+ hash: -2358155464795184173
130
130
  requirements: []
131
131
  rubyforge_project:
132
132
  rubygems_version: 1.8.25