protobuf 2.7.11-java → 2.8.0.beta1-java

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.
Files changed (41) hide show
  1. data/README.md +39 -2
  2. data/lib/protobuf.rb +17 -26
  3. data/lib/protobuf/cli.rb +106 -86
  4. data/lib/protobuf/field/float_field.rb +5 -1
  5. data/lib/protobuf/rpc/connectors/base.rb +1 -1
  6. data/lib/protobuf/rpc/connectors/zmq.rb +157 -29
  7. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +49 -0
  8. data/lib/protobuf/rpc/error/client_error.rb +5 -5
  9. data/lib/protobuf/rpc/error/server_error.rb +7 -7
  10. data/lib/protobuf/rpc/rpc.pb.rb +13 -12
  11. data/lib/protobuf/rpc/servers/evented_runner.rb +11 -6
  12. data/lib/protobuf/rpc/servers/socket/server.rb +19 -15
  13. data/lib/protobuf/rpc/servers/socket_runner.rb +21 -18
  14. data/lib/protobuf/rpc/servers/zmq/broker.rb +104 -94
  15. data/lib/protobuf/rpc/servers/zmq/server.rb +263 -43
  16. data/lib/protobuf/rpc/servers/zmq/util.rb +18 -6
  17. data/lib/protobuf/rpc/servers/zmq/worker.rb +102 -39
  18. data/lib/protobuf/rpc/servers/zmq_runner.rb +31 -20
  19. data/lib/protobuf/rpc/service.rb +24 -12
  20. data/lib/protobuf/rpc/service_directory.rb +206 -0
  21. data/lib/protobuf/rpc/stat.rb +1 -1
  22. data/lib/protobuf/version.rb +1 -1
  23. data/proto/dynamic_discovery.proto +44 -0
  24. data/spec/benchmark/tasks.rb +1 -3
  25. data/spec/functional/socket_server_spec.rb +6 -5
  26. data/spec/functional/zmq_server_spec.rb +59 -30
  27. data/spec/lib/protobuf/cli_spec.rb +49 -54
  28. data/spec/lib/protobuf/enum_spec.rb +1 -1
  29. data/spec/lib/protobuf/rpc/client_spec.rb +1 -1
  30. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +43 -1
  31. data/spec/lib/protobuf/rpc/servers/evented_server_spec.rb +2 -1
  32. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +9 -8
  33. data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +24 -19
  34. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +5 -5
  35. data/spec/lib/protobuf/rpc/service_directory_spec.rb +183 -0
  36. data/spec/support/server.rb +21 -12
  37. data/spec/support/test/resource.pb.rb +6 -0
  38. data/spec/support/test/resource.proto +5 -0
  39. data/spec/support/test/resource_service.rb +7 -0
  40. metadata +11 -11
  41. data/spec/lib/protobuf/rpc/servers/zmq/broker_spec.rb +0 -31
@@ -6,7 +6,7 @@ describe Protobuf::Enum do
6
6
 
7
7
  before(:all) do
8
8
  Test::EnumTestType.define(:MINUS_ONE, -1)
9
- Test::EnumTestType.define(name, tag)
9
+ Test::EnumTestType.define(:THREE, 3)
10
10
  end
11
11
 
12
12
  describe '.define' do
@@ -6,7 +6,7 @@ describe Protobuf::Rpc::Client do
6
6
  load 'protobuf/evented.rb'
7
7
  end
8
8
 
9
- context "when using fiber based calls" do
9
+ context "when using fiber based calls", :skip => true do
10
10
  it "waits for response" do
11
11
  EventMachine.fiber_run do
12
12
  StubServer.new(:delay => 1) do |server|
@@ -2,6 +2,16 @@ require 'spec_helper'
2
2
  require 'protobuf/zmq'
3
3
 
4
4
  describe ::Protobuf::Rpc::Connectors::Zmq do
5
+ subject { described_class.new(options) }
6
+
7
+ let(:options) {{
8
+ :service => "Test::Service",
9
+ :method => "find",
10
+ :timeout => 3,
11
+ :host => "127.0.0.1",
12
+ :port => "9400"
13
+ }}
14
+
5
15
  let(:socket_mock) do
6
16
  sm = mock(::ZMQ::Socket)
7
17
  sm.stub(:connect).and_return(0)
@@ -14,9 +24,41 @@ describe ::Protobuf::Rpc::Connectors::Zmq do
14
24
  zc
15
25
  end
16
26
 
17
- before(:each) do
27
+ before do
18
28
  ::ZMQ::Context.stub(:new).and_return(zmq_context_mock)
19
29
  end
20
30
 
31
+ describe "#lookup_server_uri" do
32
+ let(:service_directory) { double('ServiceDirectory', :running? => running? ) }
33
+ let(:listing) { double('Listing', :address => '127.0.0.2', :port => 9399) }
34
+ let(:running?) { true }
35
+
36
+ before do
37
+ subject.stub(:service_directory) { service_directory }
38
+ end
39
+
40
+ context "when the service directory is running" do
41
+ it "searches the service directory" do
42
+ service_directory.should_receive(:lookup).and_return(listing)
43
+ subject.send(:lookup_server_uri).should eq "tcp://127.0.0.2:9399"
44
+ end
45
+
46
+ it "defaults to the options" do
47
+ service_directory.should_receive(:lookup) { nil }
48
+ subject.send(:lookup_server_uri).should eq "tcp://127.0.0.1:9400"
49
+ end
50
+ end
51
+
52
+ context "when the service directory is not running" do
53
+ let(:running?) { false }
54
+
55
+ it "does not search the directory" do
56
+ service_directory.should_not_receive(:lookup)
57
+ subject.send(:lookup_server_uri).should eq "tcp://127.0.0.1:9400"
58
+ end
59
+ end
60
+
61
+ end
62
+
21
63
  pending
22
64
  end
@@ -12,7 +12,8 @@ describe Protobuf::Rpc::Evented::Server do
12
12
 
13
13
  it "Runner provides a stop method" do
14
14
  runner_class = described_class.to_s.gsub(/Evented::Server/, "EventedRunner").constantize
15
- runner_class.respond_to?(:stop).should be_true
15
+ runner = runner_class.new({})
16
+ runner.respond_to?(:stop).should be_true
16
17
  end
17
18
 
18
19
  end
@@ -12,23 +12,24 @@ describe Protobuf::Rpc::Socket::Server do
12
12
  before(:all) do
13
13
  load 'protobuf/socket.rb'
14
14
  Thread.abort_on_exception = true
15
- server = OpenStruct.new(:server => "127.0.0.1", :port => 9399, :backlog => 100, :threshold => 100)
16
- @server_thread = Thread.new(server) { |s| Protobuf::Rpc::SocketRunner.run(s) }
17
- Thread.pass until Protobuf::Rpc::Socket::Server.running?
15
+ @options = OpenStruct.new(:host => "127.0.0.1", :port => 9399, :backlog => 100, :threshold => 100)
16
+ @runner = ::Protobuf::Rpc::SocketRunner.new(@options)
17
+ @server = @runner.instance_variable_get(:@server)
18
+ @server_thread = Thread.new(@runner) { |runner| runner.run }
19
+ Thread.pass until @server.running?
18
20
  end
19
21
 
20
22
  after(:all) do
21
- Protobuf::Rpc::SocketRunner.stop
23
+ @server.stop
22
24
  @server_thread.join
23
25
  end
24
26
 
25
27
  it "Runner provides a stop method" do
26
- runner_class = described_class.to_s.gsub(/Evented::Server/, "EventedRunner").constantize
27
- runner_class.respond_to?(:stop).should be_true
28
+ @runner.should respond_to(:stop)
28
29
  end
29
30
 
30
31
  it "provides a stop method" do
31
- described_class.respond_to?(:stop).should be_true
32
+ @server.should respond_to(:stop)
32
33
  end
33
34
 
34
35
  it "provides a Runner class" do
@@ -37,7 +38,7 @@ describe Protobuf::Rpc::Socket::Server do
37
38
  end
38
39
 
39
40
  it "signals the Server is running" do
40
- described_class.running?.should be_true
41
+ @server.should be_running
41
42
  end
42
43
 
43
44
  end
@@ -2,40 +2,45 @@ require 'spec_helper'
2
2
  require 'protobuf/rpc/servers/zmq/server'
3
3
 
4
4
  describe Protobuf::Rpc::Zmq::Server do
5
- before(:each) do
5
+ subject { described_class.new(options) }
6
+
7
+ let(:options) {{
8
+ :host => '127.0.0.1',
9
+ :port => 9399,
10
+ :worker_port => 9400,
11
+ :workers_only => true
12
+ }}
13
+
14
+ before do
6
15
  load 'protobuf/zmq.rb'
7
16
  end
8
17
 
18
+ after do
19
+ subject.teardown
20
+ end
21
+
9
22
  describe '.running?' do
10
23
  it 'returns true if running' do
11
- described_class.instance_variable_set(:@running, true)
12
- described_class.running?.should be_true
24
+ subject.instance_variable_set(:@running, true)
25
+ subject.running?.should be_true
13
26
  end
14
27
 
15
28
  it 'returns false if not running' do
16
- described_class.instance_variable_set(:@running, false)
17
- described_class.running?.should be_false
29
+ subject.instance_variable_set(:@running, false)
30
+ subject.running?.should be_false
18
31
  end
19
32
  end
20
33
 
21
34
  describe '.stop' do
22
- # keep threads instance variable from retaining any thread mocks we've
23
- # created (breaks tests down the line, otherwise)
24
- after(:each) do
25
- described_class.instance_variable_set(:@threads, [])
26
- end
27
-
28
- it 'lets all threads stop' do
29
- thread_mock = double(Thread)
30
- thread_mock.should_receive(:join).and_return(thread_mock)
31
- described_class.instance_variable_set(:@threads, [thread_mock])
32
- described_class.stop
35
+ it 'signals shutdown' do
36
+ subject.should_receive(:signal_shutdown)
37
+ subject.stop
33
38
  end
34
39
 
35
40
  it 'sets running to false' do
36
- described_class.instance_variable_set(:@threads, [])
37
- described_class.stop
38
- described_class.instance_variable_get(:@running).should be_false
41
+ subject.instance_variable_set(:@workers, [])
42
+ subject.stop
43
+ subject.instance_variable_get(:@running).should be_false
39
44
  end
40
45
  end
41
46
  end
@@ -13,26 +13,26 @@ describe ::Protobuf::Rpc::Zmq::Util do
13
13
  describe '#zmq_error_check' do
14
14
  it 'raises when the error code is less than 0' do
15
15
  expect {
16
- subject.zmq_error_check(-1)
17
- }.to raise_error
16
+ subject.zmq_error_check(-1, :test)
17
+ }.to raise_error(/test/)
18
18
  end
19
19
 
20
20
  it 'retrieves the error string from ZeroMQ' do
21
21
  ZMQ::Util.stub(:error_string).and_return('an error from zmq')
22
22
  expect {
23
- subject.zmq_error_check(-1)
23
+ subject.zmq_error_check(-1, :test)
24
24
  }.to raise_error(RuntimeError, /an error from zmq/i)
25
25
  end
26
26
 
27
27
  it 'does nothing if the error code is > 0' do
28
28
  expect {
29
- subject.zmq_error_check(1)
29
+ subject.zmq_error_check(1, :test)
30
30
  }.to_not raise_error
31
31
  end
32
32
 
33
33
  it 'does nothing if the error code is == 0' do
34
34
  expect {
35
- subject.zmq_error_check(0)
35
+ subject.zmq_error_check(0, :test)
36
36
  }.to_not raise_error
37
37
  end
38
38
  end
@@ -0,0 +1,183 @@
1
+ require 'spec_helper'
2
+
3
+ require 'protobuf/rpc/service_directory'
4
+
5
+ describe ::Protobuf::Rpc::ServiceDirectory do
6
+ let(:instance) { ::Protobuf::Rpc::ServiceDirectory.instance }
7
+
8
+ def listings
9
+ instance.instance_variable_get(:@listings)
10
+ end
11
+
12
+ def duration
13
+ start = Time.now.to_f
14
+ yield
15
+ Time.now.to_f - start
16
+ end
17
+
18
+ after do
19
+ instance.stop
20
+ end
21
+
22
+ it "is a singleton" do
23
+ instance.should be_a_kind_of(Singleton)
24
+ end
25
+
26
+ describe "#lookup" do
27
+ let(:server) { double('server', :uuid => '123',
28
+ :services => ['Known::Service'],
29
+ :address => "0.0.0.0",
30
+ :port => 9999,
31
+ :ttl => 15) }
32
+ let(:listing) { ::Protobuf::Rpc::ServiceDirectory::Listing.new(server) }
33
+
34
+ it "returns a listing for the given service" do
35
+ instance.add_listing_for(server)
36
+ instance.lookup("Known::Service").should eq listing
37
+ end
38
+
39
+ it "returns random listings" do
40
+ instance.add_listing_for double(:uuid => 1, :ttl => 5, :services => ["Test"])
41
+ instance.add_listing_for double(:uuid => 2, :ttl => 5, :services => ["Test"])
42
+
43
+ uuids = 100.times.map { instance.lookup("Test").uuid }
44
+ uuids.count(1).should be_within(25).of(50)
45
+ uuids.count(2).should be_within(25).of(50)
46
+ end
47
+
48
+ it "does not return expired listings" do
49
+ instance.instance_variable_set(:@listings, {
50
+ '1' => double(:current? => false, :services => ["Test"]),
51
+ })
52
+
53
+ instance.lookup("Test").should be_nil
54
+ end
55
+ end
56
+
57
+ describe "#remove_expired_listings" do
58
+ before do
59
+ instance.instance_variable_set(:@listings, {
60
+ '1' => double(:expired? => true),
61
+ '2' => double(:expired? => true),
62
+ '3' => double(:expired? => false),
63
+ })
64
+ end
65
+
66
+ it "removes expired listings" do
67
+ expect {
68
+ instance.remove_expired_listings
69
+ }.to change(listings, :size).from(3).to(1)
70
+ listings.keys.should eq ['3']
71
+ end
72
+ end
73
+
74
+ describe "#start" do
75
+ it "creates a thread" do
76
+ Thread.should_receive(:new)
77
+ instance.start
78
+ end
79
+
80
+ it "initializes the socket" do
81
+ instance.should_receive :init_socket
82
+ instance.start
83
+ end
84
+
85
+ it "calls #run" do
86
+ instance.should_receive(:run)
87
+ instance.start
88
+ sleep 0.01
89
+ end
90
+
91
+ it "changes the running state" do
92
+ expect {
93
+ instance.start
94
+ }.to change(instance, :running?).from(false).to(true)
95
+ end
96
+ end
97
+
98
+ describe "#wait_for" do
99
+ it "returns a listing for the given service" do
100
+ server = double(:uuid => 1, :ttl => 5, :services => ["Test"])
101
+ instance.add_listing_for server
102
+ instance.lookup("Test").should eq server
103
+ end
104
+
105
+ it "depends on #lookup" do
106
+ instance.stub(:lookup).with("Hayoob!") { "yup" }
107
+ instance.wait_for("Hayoob!").should eq "yup"
108
+ end
109
+
110
+ it "waits for the service to appear" do
111
+ server = double(:uuid => 1, :ttl => 5, :services => ["Test"])
112
+
113
+ t = Thread.new do
114
+ sleep 0.5
115
+ instance.add_listing_for server
116
+ end
117
+
118
+ duration { instance.wait_for("Test") }.should be_within(0.01).of(0.5)
119
+ t.join
120
+ end
121
+
122
+ it "returns nil if the service doesn't appear withint the timeout period" do
123
+ server = double(:uuid => 1, :ttl => 5, :services => ["Test"])
124
+
125
+ t = Thread.new do
126
+ sleep 0.5
127
+ instance.add_listing_for server
128
+ end
129
+
130
+ instance.wait_for("Test", 0.1).should be_nil
131
+ t.join
132
+ end
133
+ end
134
+
135
+ describe "a running service directory" do
136
+ let(:socket) { UDPSocket.new }
137
+
138
+ def thread
139
+ instance.instance_variable_get(:@thread)
140
+ end
141
+
142
+ before do
143
+ described_class.start do |config|
144
+ config.address = "127.0.0.1"
145
+ config.port = 33333
146
+ end
147
+
148
+ socket.connect described_class.address, described_class.port
149
+ end
150
+
151
+ context "receiving a heartbeat" do
152
+ let(:server) { ::Protobuf::Rpc::DynamicDiscovery::Server.new(:uuid => 'heartbeat', :address => '127.0.0.1') }
153
+ let(:beacon) { ::Protobuf::Rpc::DynamicDiscovery::Beacon.new(
154
+ :server => server,
155
+ :beacon_type => ::Protobuf::Rpc::DynamicDiscovery::BeaconType::HEARTBEAT
156
+ )}
157
+ let(:payload) { beacon.serialize_to_string }
158
+
159
+ it "adds a listing" do
160
+ instance.should_receive(:add_listing_for).with(server)
161
+ instance.should_receive(:remove_expired_listings)
162
+ socket.send(payload, 0)
163
+ sleep 0.01
164
+ end
165
+ end
166
+
167
+ context "receiving a flatline" do
168
+ let(:server) { ::Protobuf::Rpc::DynamicDiscovery::Server.new(:uuid => 'flatline', :address => '127.0.0.1') }
169
+ let(:beacon) { ::Protobuf::Rpc::DynamicDiscovery::Beacon.new(
170
+ :server => server,
171
+ :beacon_type => ::Protobuf::Rpc::DynamicDiscovery::BeaconType::FLATLINE
172
+ )}
173
+ let(:payload) { beacon.serialize_to_string }
174
+
175
+ it "removes a listing" do
176
+ instance.should_receive(:remove_listing_for).with(server)
177
+ instance.should_receive(:remove_expired_listings)
178
+ socket.send(payload, 0)
179
+ sleep 0.01
180
+ end
181
+ end
182
+ end
183
+ end
@@ -53,8 +53,10 @@ class StubServer
53
53
 
54
54
  def start
55
55
  case
56
- when @options.server == Protobuf::Rpc::Evented::Server then start_em_server
57
- when @options.server == Protobuf::Rpc::Zmq::Server then start_zmq_server
56
+ when @options.server == Protobuf::Rpc::Evented::Server
57
+ start_em_server
58
+ when @options.server == Protobuf::Rpc::Zmq::Server
59
+ start_zmq_server
58
60
  else
59
61
  start_socket_server
60
62
  end
@@ -67,18 +69,25 @@ class StubServer
67
69
  end
68
70
 
69
71
  def start_em_server
70
- @server_handle = EventMachine.start_server(@options.host, @options.port, StubProtobufServerFactory.build(@options.delay))
72
+ @server_handle = EventMachine.start_server(
73
+ @options.host,
74
+ @options.port,
75
+ StubProtobufServerFactory.build(@options.delay)
76
+ )
71
77
  end
72
78
 
73
79
  def start_socket_server
74
- @sock_server = Thread.new(@options) { |opt| Protobuf::Rpc::SocketRunner.run(opt) }
75
- @sock_server.abort_on_exception = true # Set for testing purposes
76
- Thread.pass until Protobuf::Rpc::Socket::Server.running?
80
+ @sock_runner = ::Protobuf::Rpc::SocketRunner.new(opt)
81
+ @sock_thread = Thread.new(@sock_runner) { |runner| runner.run }
82
+ @sock_thread.abort_on_exception = true # Set for testing purposes
83
+ Thread.pass until @sock_runner.running?
77
84
  end
78
85
 
79
86
  def start_zmq_server
80
- @zmq_server = Thread.new(@options) { |opt| Protobuf::Rpc::ZmqRunner.run(opt) }
81
- Thread.pass until Protobuf::Rpc::Zmq::Server.running?
87
+ @zmq_runnger = ::Protobuf::Rpc::ZmqRunner.new(opt)
88
+ @zmq_thread = Thread.new(@zmq_runner) { |runner| runner.run }
89
+ @zmq_thread.abort_on_exception = true # Set for testing purposes
90
+ Thread.pass until @zmq_runner.running?
82
91
  end
83
92
 
84
93
  def stop
@@ -86,11 +95,11 @@ class StubServer
86
95
  when @options.server == Protobuf::Rpc::Evented::Server then
87
96
  EventMachine.stop_server(@server_handle) if @server_handle
88
97
  when @options.server == Protobuf::Rpc::Zmq::Server then
89
- Protobuf::Rpc::ZmqRunner.stop
90
- @zmq_server.join if @zmq_server
98
+ @zmq_runner.try :stop
99
+ @zmq_thread.join if @zmq_thread
91
100
  else
92
- Protobuf::Rpc::SocketRunner.stop
93
- @sock_server.join if @sock_server
101
+ @sock_runner.stop
102
+ @sock_thread.join if @sock_thread
94
103
  end
95
104
 
96
105
  @running = false