pb_actor 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7b680bcef360e5d1e59a276d633ceb22aee7f496
4
- data.tar.gz: cd56e2019501bf107915673daf02c4733711d6b4
3
+ metadata.gz: 769f131d2a68aac7e498d83a94e10698b93baa9b
4
+ data.tar.gz: 3fa73cbcab4e355beb9ee81c0c930722476797d5
5
5
  SHA512:
6
- metadata.gz: b984d664769c243b51738419ea67d4363a61716ea6e321403225e80eee72d74c4f012fa540b4d76b37ac44d1c4cef8cd5d33e062580da149be54f933ed8940a2
7
- data.tar.gz: 71aed55f5256e8f56544162e812863829b209f5494107927a41d35ed9037e2bcf74295ad1025706d46cf9af588e198609109d767866cffcef10ebdac600d4f6f
6
+ metadata.gz: 1afb16fa5de4f6e2b504f02391505e3089285b0d32f2ba4a607a0f22b7c2a926fc6be8f7535ad9967ec00af2f2a7901ba14d016257361b5909fd98d115956c5c
7
+ data.tar.gz: bc702fb0db8595fe9fa424ddda87e92a5987aaf88a62a20a9a3a11ad34122a1fbbedee729a51edc2a4888cee9963a3d5546fa078400f61a1bec30a69874b26fc
data/README.md CHANGED
@@ -20,6 +20,7 @@ Or install it yourself as:
20
20
 
21
21
  ```ruby
22
22
  require 'pb_actor'
23
+ require 'benchmark'
23
24
 
24
25
  class Test
25
26
  include PbActor
@@ -36,22 +37,36 @@ class Test
36
37
  end
37
38
  end
38
39
 
39
- f = Test.new
40
+ t = Test.new
40
41
  #=> <PbActor::Proxy:0x00000002106448 @origin=#<Test:0x00000002106470>, @pid=23487, @rd=#<IO:fd 7>, @wr=#<IO:fd 10>>
41
42
 
42
- f.alive?
43
+ t.alive?
43
44
  #=> true
44
45
 
45
- f.fib(30)
46
+ t.fib(30)
46
47
  #=> 1346269
47
48
 
48
- f.async.p_fib(30)
49
+ t.async.p_fib(30)
49
50
  #=> nil
50
51
  # 1346269
51
52
 
52
- f.terminate
53
- f.alive?
53
+ t.terminate
54
+ t.alive?
54
55
  #=> false
56
+
57
+ def fib n
58
+ if n < 2
59
+ 1
60
+ else
61
+ fib(n - 1) + fib(n - 2)
62
+ end
63
+ end
64
+
65
+ Benchmark.bm do |bm|
66
+ bm.report{puts (30..35).map{|n| fib(n)}.reduce(:+)}
67
+ bm.report{puts (30..35).map{|n| Test.new.future.fib(n)}.map(&:value).reduce(:+)}
68
+ end
69
+ #=> Try it youself!
55
70
  ```
56
71
 
57
72
  ## Contributing
@@ -1,23 +1,28 @@
1
1
  require 'timeout'
2
+ require 'securerandom'
2
3
 
3
4
  module PbActor
4
5
  class DeadActorError < StandardError
5
6
  end
6
7
 
7
- class BasicProxy
8
- module Message
9
- class << self
10
- def send msg, wr
11
- Marshal.dump(msg, wr)
12
- rescue Errno::EPIPE => e
13
- raise DeadActorError, 'dead actor call'
14
- end
8
+ module Message
9
+ class << self
10
+ def send msg, wr
11
+ Marshal.dump(msg, wr)
12
+ rescue Errno::EPIPE => e
13
+ raise DeadActorError, 'dead actor call'
14
+ end
15
15
 
16
- def recv rd
17
- Marshal.load rd
18
- end
16
+ def recv rd
17
+ Marshal.load rd
19
18
  end
20
19
  end
20
+ end
21
+
22
+ class BasicProxy
23
+ def initialize origin, pid, wr, rd
24
+ @origin, @pid, @wr, @rd = origin, pid, wr, rd
25
+ end
21
26
 
22
27
  def alive?
23
28
  begin
@@ -49,12 +54,24 @@ module PbActor
49
54
  cr, pw = IO.pipe
50
55
  @pid = fork do
51
56
  [pr, pw].each &:close
57
+ @future_values = {}
52
58
  loop do
53
- type, method, *args = Message.recv cr
59
+ type, id, method, *args = begin
60
+ Message.recv cr
61
+ rescue EOFError => e
62
+ [:terminate]
63
+ end
54
64
  case type
55
- when :method_call, :async_method_call
56
- value = @origin.public_send method, *args
57
- Message.send([:return_value, value], cw) if type == :method_call
65
+ when :async_method_call
66
+ @origin.public_send method, *args
67
+ when :future_method_call
68
+ @future_values[id] = @origin.public_send method, *args
69
+ when :future_value_get
70
+ Message.send(if @future_values.has_key? id
71
+ [:future_value, @future_values.delete(id)]
72
+ else
73
+ [:no_value]
74
+ end, cw)
58
75
  when :terminate
59
76
  exit
60
77
  else
@@ -69,18 +86,15 @@ module PbActor
69
86
 
70
87
  def method_missing method, *args, &blk
71
88
  super
72
- Message.send([:method_call, method, *args], @wr)
73
- type, value = Message.recv @rd
74
- case type
75
- when :return_value
76
- value
77
- else
78
- raise "what happend!? receive #{type}"
79
- end
89
+ future.method_missing(method, *args).value
80
90
  end
81
91
 
82
92
  def async
83
- AsyncProxy.new @origin, @pid, @wr
93
+ AsyncProxy.new @origin, @pid, @wr, @rd
94
+ end
95
+
96
+ def future
97
+ FutureProxy.new @origin, @pid, @wr, @rd
84
98
  end
85
99
 
86
100
  def terminate
@@ -97,14 +111,39 @@ module PbActor
97
111
  end
98
112
 
99
113
  class AsyncProxy < BasicProxy
100
- def initialize origin, pid, wr
101
- @origin, @pid, @wr = origin, pid, wr
114
+ def method_missing method, *args, &blk
115
+ super
116
+ Message.send [:async_method_call, nil, method, *args], @wr
117
+ nil
102
118
  end
119
+ end
103
120
 
121
+ class FutureProxy < BasicProxy
104
122
  def method_missing method, *args, &blk
105
123
  super
106
- Message.send [:async_method_call, method, *args], @wr
107
- nil
124
+ id = SecureRandom.uuid
125
+ Message.send [:future_method_call, id, method, *args], @wr
126
+ Future.new id, @wr, @rd
127
+ end
128
+ end
129
+
130
+ class Future
131
+ def initialize id, wr, rd
132
+ @id = id
133
+ @wr= wr
134
+ @rd = rd
135
+ end
136
+
137
+ def value
138
+ loop do
139
+ Message.send [:future_value_get, @id], @wr
140
+ type, value = Message.recv @rd
141
+ if type == :future_value
142
+ break value
143
+ else
144
+ sleep 0.01
145
+ end
146
+ end
108
147
  end
109
148
  end
110
149
  end
@@ -1,3 +1,3 @@
1
1
  module PbActor
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -50,6 +50,13 @@ describe PbActor do
50
50
  @test.bar.should == 'bar'
51
51
  end
52
52
 
53
+ it 'future call should work' do
54
+ params = [1, 2, 3]
55
+ futures = params.map{ |n| @test.future.hello n }
56
+ futures.each{ |f| f.should.is_a? PbActor::Future }
57
+ futures.map(&:value).should == params.map{ |n| "hello #{n}"}
58
+ end
59
+
53
60
  it 'terminate should work' do
54
61
  @test.alive?.should == true
55
62
  @test.terminate
@@ -69,5 +76,6 @@ describe PbActor do
69
76
  it 'to_s should correct' do
70
77
  @test.to_s.should == 'PbActor::Proxy(Test)'
71
78
  @test.async.to_s.should == 'PbActor::AsyncProxy(Test)'
79
+ @test.future.to_s.should == 'PbActor::FutureProxy(Test)'
72
80
  end
73
81
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pb_actor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - jjy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-09 00:00:00.000000000 Z
11
+ date: 2013-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler