zmachine 0.1.3 → 0.2.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.
@@ -0,0 +1,16 @@
1
+ require 'zmachine/connection_manager'
2
+
3
+ include ZMachine
4
+
5
+ module TCPEchoServer
6
+ end
7
+
8
+ module TCPEchoClient
9
+ end
10
+
11
+ describe ConnectionManager do
12
+
13
+ context 'TCP' do
14
+ end
15
+
16
+ end
@@ -0,0 +1,56 @@
1
+ require 'zmachine/connection'
2
+
3
+ include ZMachine
4
+
5
+ describe Connection do
6
+
7
+ before(:each) do
8
+ @server = Connection.new.bind("0.0.0.0", 0)
9
+ @port = @server.channel.socket.socket.local_port
10
+ @client = Connection.new.connect("0.0.0.0", @port)
11
+ end
12
+
13
+ after(:each) do
14
+ @client.close
15
+ @server.close
16
+ end
17
+
18
+ let(:data) { "foo" }
19
+
20
+ context 'triggers' do
21
+
22
+ it 'triggers acceptable' do
23
+ @server.channel.should_receive(:accept).once.and_call_original
24
+ @server.should_receive(:connection_accepted).once
25
+ connection = @server.acceptable!
26
+ expect(connection).to be_connected
27
+ end
28
+
29
+ it 'triggers connectable' do
30
+ @server.acceptable!
31
+ @client.channel.should_receive(:finish_connecting).once.and_call_original
32
+ @client.should_receive(:connection_completed).once
33
+ @client.connectable!
34
+ expect(@client).to be_connected
35
+ end
36
+
37
+ it 'triggers writable' do
38
+ @server.acceptable!
39
+ @client.connectable!
40
+ @client.send_data(data.to_java_bytes)
41
+ @client.channel.should_receive(:write_outbound_data).and_call_original
42
+ @client.writable!
43
+ end
44
+
45
+ it 'triggers readable' do
46
+ connection = @server.acceptable!
47
+ @client.connectable!
48
+ @client.send_data(data.to_java_bytes)
49
+ @client.writable!
50
+ connection.channel.should_receive(:read_inbound_data).and_call_original
51
+ connection.should_receive(:receive_data).once
52
+ connection.readable!
53
+ end
54
+
55
+ end
56
+ end
@@ -1,12 +1,4 @@
1
- require 'spec_helper'
2
- require 'lib/zmachine/hashed_wheel'
3
-
4
- describe ZMachine::HashedWheelTimeout do
5
- it 'calculates the stop index correctly'
6
- it 'calculates remaining rounds correctly'
7
- it 'can be cancelled'
8
- it 'supports an action'
9
- end
1
+ require 'zmachine/hashed_wheel'
10
2
 
11
3
  describe ZMachine::HashedWheel do
12
4
  let(:wheel) { ZMachine::HashedWheel.new(16, 100) }
@@ -35,15 +27,26 @@ describe ZMachine::HashedWheel do
35
27
  expect(timedout.length).to eq(1)
36
28
  end
37
29
 
38
- it 'calculates the timeouted set correctly' do
30
+ it 'calculates the timeout set correctly' do
39
31
  now = wheel.reset
40
32
  wheel.add 10
41
33
  wheel.add 40
42
34
  wheel.add 1900
43
35
  wheel.add 3300
44
36
  wheel.add 4000
45
- timedout = wheel.advance( now + 3900 * 1_000_000)
37
+ timedout = wheel.advance(now + 3900 * 1_000_000)
46
38
  expect(timedout).to be
47
39
  expect(timedout.length).to eq(4)
48
40
  end
49
- end
41
+
42
+ it 'cancels timers correctly' do
43
+ now = wheel.reset
44
+ t1 = wheel.add 90
45
+ t2 = wheel.add 110
46
+ t1.cancel
47
+ timedout = wheel.advance(now + 200 * 1_000_000)
48
+ expect(timedout).to eq([t2])
49
+ expect(timedout.length).to eq(1)
50
+ end
51
+
52
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,17 +1,25 @@
1
- # This file was generated by the `rspec --init` command. Conventionally, all
2
- # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
- # Require this file using `require "spec_helper"` to ensure that it is only
4
- # loaded once.
5
- #
6
- # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
1
+ # encoding: utf-8
2
+
3
+ require 'bundler/setup'
4
+
5
+ require 'rspec'
6
+ require 'simplecov'
7
+
8
+ class SimpleCov::Formatter::QualityFormatter
9
+ def format(result)
10
+ SimpleCov::Formatter::HTMLFormatter.new.format(result)
11
+ File.open("coverage/covered_percent", "w") do |f|
12
+ f.puts result.source_files.covered_percent.to_f
13
+ end
14
+ end
15
+ end
16
+
17
+ SimpleCov.formatter = SimpleCov::Formatter::QualityFormatter
18
+
19
+ SimpleCov.start do
20
+ add_filter '/spec/'
21
+ end
22
+
7
23
  RSpec.configure do |config|
8
24
  config.treat_symbols_as_metadata_keys_with_true_values = true
9
- config.run_all_when_everything_filtered = true
10
- config.filter_run :focus
11
-
12
- # Run specs in random order to surface order dependencies. If you find an
13
- # order dependency and want to debug it, you can fix the order by providing
14
- # the seed, which is printed after each run.
15
- # --seed 1234
16
- config.order = 'random'
17
25
  end
@@ -0,0 +1,109 @@
1
+ require 'zmachine/tcp_channel'
2
+
3
+ include ZMachine
4
+
5
+ describe ZMachine::TCPChannel do
6
+
7
+ before(:each) do
8
+ @server = TCPChannel.new
9
+ @server.bind("0.0.0.0", 0)
10
+ @port = @server.socket.socket.local_port
11
+ @client = TCPChannel.new
12
+ @client.connect("0.0.0.0", @port)
13
+ end
14
+
15
+ after(:each) do
16
+ @client.close
17
+ @server.close
18
+ end
19
+
20
+ let(:data) { "foo" }
21
+
22
+ context '#bind' do
23
+
24
+ it 'binds a server socket' do
25
+ expect(@server).to be_bound
26
+ end
27
+
28
+ it 'accepts client connections' do
29
+ channel = @server.accept
30
+ expect(channel).to be_a(TCPChannel)
31
+ expect(channel).to be_connected
32
+ end
33
+
34
+ end
35
+
36
+ context '#connect' do
37
+
38
+ it 'connects to a pending server socket' do
39
+ expect(@client).to be_connection_pending
40
+ end
41
+
42
+ it 'connects to an accepted server socket' do
43
+ @server.accept
44
+ @client.finish_connecting
45
+ expect(@client).to be_connected
46
+ end
47
+
48
+ end
49
+
50
+ context '#send/recv' do
51
+
52
+ before(:each) do
53
+ @channel = @server.accept
54
+ @client.finish_connecting
55
+ @client.send_data(data.to_java_bytes)
56
+ end
57
+
58
+ it 'writes outbound buffers to the socket' do
59
+ expect(@client.write_outbound_data).to eq(true)
60
+ end
61
+
62
+ it 'receives data sent from the client' do
63
+ @client.write_outbound_data
64
+ received = @channel.read_inbound_data
65
+ expect(received).to eq(data)
66
+ end
67
+
68
+ it 'receives data sent from the server' do
69
+ @client.write_outbound_data
70
+ received = @channel.read_inbound_data
71
+ @channel.send_data(data.to_java_bytes)
72
+ @channel.write_outbound_data
73
+ received = @client.read_inbound_data
74
+ expect(received).to eq(data)
75
+ end
76
+
77
+ end
78
+
79
+ context '#close' do
80
+
81
+ it 'closes the client connection' do
82
+ @client.close
83
+ expect(@client).to be_closed
84
+ end
85
+
86
+ it 'closes the server connection' do
87
+ @server.close
88
+ expect(@server).to be_closed
89
+ end
90
+
91
+ it 'closes the accepted connection' do
92
+ channel = @server.accept
93
+ channel.close
94
+ expect(channel).to be_closed
95
+ end
96
+
97
+ it 'closes the connection after writing' do
98
+ channel = @server.accept
99
+ @client.finish_connecting
100
+ @client.send_data(data.to_java_bytes)
101
+ @client.close_after_writing
102
+ expect(@client).to be_connected
103
+ @client.write_outbound_data
104
+ expect(@client).not_to be_connected
105
+ end
106
+
107
+ end
108
+
109
+ end
@@ -0,0 +1,113 @@
1
+ require 'zmachine/zmq_channel'
2
+
3
+ include ZMachine
4
+
5
+ describe ZMachine::ZMQChannel do
6
+
7
+ before(:each) do
8
+ @server = ZMQChannel.new(ZMQ::REP)
9
+ @port = @server.bind("tcp://*:*")
10
+ @client = ZMQChannel.new(ZMQ::REQ)
11
+ @client.connect("tcp://0.0.0.0:#{@port}")
12
+ end
13
+
14
+ after(:each) do
15
+ @client.close
16
+ @server.close
17
+ end
18
+
19
+ after(:all) do
20
+ ZMachine.context.destroy
21
+ end
22
+
23
+ let(:data) { "foo" }
24
+
25
+ context '#bind' do
26
+
27
+ it 'binds a server socket' do
28
+ expect(@server).to be_bound
29
+ end
30
+
31
+ end
32
+
33
+ context '#connect' do
34
+
35
+ it 'connects to a server socket' do
36
+ expect(@client).to be_connected
37
+ end
38
+
39
+ end
40
+
41
+ context '#send/recv' do
42
+
43
+ it 'writes outbound buffers to the socket' do
44
+ @client.send_data([data.to_java_bytes])
45
+ expect(@client.write_outbound_data).to eq(true)
46
+ end
47
+
48
+ it 'receives data sent from the client' do
49
+ @client.send_data([data.to_java_bytes])
50
+ @client.write_outbound_data
51
+ received = String.from_java_bytes(@server.read_inbound_data.first)
52
+ expect(received).to eq(data)
53
+ end
54
+
55
+ it 'receives data sent from the server' do
56
+ @client.send_data([data.to_java_bytes])
57
+ @client.write_outbound_data
58
+ received = String.from_java_bytes(@server.read_inbound_data.first)
59
+ @server.send_data([data.to_java_bytes])
60
+ @server.write_outbound_data
61
+ received = String.from_java_bytes(@client.read_inbound_data.first)
62
+ expect(received).to eq(data)
63
+ end
64
+
65
+ it 'sends and receives multipart messages' do
66
+ parts = %w(foo bar baz)
67
+ @client.send_data(parts.map(&:to_java_bytes))
68
+ @client.write_outbound_data
69
+ received = @server.read_inbound_data.map do |part|
70
+ String.from_java_bytes(part)
71
+ end
72
+ expect(received).to eq(parts)
73
+ end
74
+
75
+ it 'queues data when ZMQ is MIA' do
76
+ socket = @client.socket
77
+ # https://github.com/jruby/jruby/wiki/Persistence#deprecating-proxy-caching
78
+ Java::OrgZeromq::ZMQ::Socket.__persistent__ = true
79
+ socket.stub(:send_byte_array) { socket.unstub(:send_byte_array); raise ZMQException.new(nil) }
80
+ @client.send_data([data.to_java_bytes])
81
+ expect(@client.can_send?).to eq(true)
82
+ @client.write_outbound_data
83
+ expect(@client.can_send?).to eq(false)
84
+ end
85
+
86
+ end
87
+
88
+ context '#close' do
89
+
90
+ it 'closes the client connection' do
91
+ @client.close
92
+ expect(@client).to be_closed
93
+ end
94
+
95
+ it 'closes the server connection' do
96
+ @server.close
97
+ expect(@server).to be_closed
98
+ end
99
+
100
+ it 'closes the connection after writing' do
101
+ @client.send_data([data.to_java_bytes])
102
+ @client.close_after_writing
103
+ @client.write_outbound_data
104
+ expect(@client).not_to be_connected
105
+ end
106
+
107
+ end
108
+
109
+ it 'has no concept of a peer' do
110
+ expect{@client.peer}.to raise_error(RuntimeError)
111
+ end
112
+
113
+ end
data/zmachine.gemspec CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "zmachine"
5
- spec.version = "0.1.3"
5
+ spec.version = "0.2.0"
6
6
  spec.authors = ["LiquidM, Inc."]
7
- spec.email = ["tech@liquidm.com"]
7
+ spec.email = ["opensource@liquidm.com"]
8
8
  spec.description = %q{pure JRuby multi-threaded mostly EventMachine compatible event loop}
9
9
  spec.summary = %q{pure JRuby multi-threaded mostly EventMachine compatible event loop}
10
10
  spec.homepage = "https://github.com/madvertise/zmachine"
@@ -15,6 +15,8 @@ Gem::Specification.new do |spec|
15
15
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
16
16
  spec.require_paths = ["lib"]
17
17
 
18
+ spec.add_dependency "madvertise-ext"
19
+
18
20
  spec.add_development_dependency "bundler", "~> 1.3"
19
21
  spec.add_development_dependency "rake"
20
22
  spec.add_development_dependency "rspec"
metadata CHANGED
@@ -1,75 +1,95 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zmachine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - LiquidM, Inc.
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-05 00:00:00.000000000 Z
11
+ date: 2013-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: madvertise-ext
15
+ version_requirements: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
15
20
  requirement: !ruby/object:Gem::Requirement
16
21
  requirements:
17
- - - ~>
22
+ - - '>='
18
23
  - !ruby/object:Gem::Version
19
- version: '1.3'
20
- type: :development
24
+ version: '0'
21
25
  prerelease: false
26
+ type: :runtime
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
22
29
  version_requirements: !ruby/object:Gem::Requirement
23
30
  requirements:
24
31
  - - ~>
25
32
  - !ruby/object:Gem::Version
26
33
  version: '1.3'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
34
  requirement: !ruby/object:Gem::Requirement
30
35
  requirements:
31
- - - ! '>='
36
+ - - ~>
32
37
  - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
38
+ version: '1.3'
35
39
  prerelease: false
40
+ type: :development
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
36
43
  version_requirements: !ruby/object:Gem::Requirement
37
44
  requirements:
38
- - - ! '>='
45
+ - - '>='
39
46
  - !ruby/object:Gem::Version
40
47
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec
43
48
  requirement: !ruby/object:Gem::Requirement
44
49
  requirements:
45
- - - ! '>='
50
+ - - '>='
46
51
  - !ruby/object:Gem::Version
47
52
  version: '0'
48
- type: :development
49
53
  prerelease: false
54
+ type: :development
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
50
57
  version_requirements: !ruby/object:Gem::Requirement
51
58
  requirements:
52
- - - ! '>='
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - '>='
53
65
  - !ruby/object:Gem::Version
54
66
  version: '0'
67
+ prerelease: false
68
+ type: :development
55
69
  description: pure JRuby multi-threaded mostly EventMachine compatible event loop
56
70
  email:
57
- - tech@liquidm.com
71
+ - opensource@liquidm.com
58
72
  executables: []
59
73
  extensions: []
60
74
  extra_rdoc_files: []
61
75
  files:
62
76
  - .gitignore
77
+ - .rspec
78
+ - .ruby-version
63
79
  - Gemfile
64
80
  - LICENSE.txt
65
81
  - README.md
66
82
  - Rakefile
83
+ - benchmarks/benchmark.sh
84
+ - benchmarks/tcp_channel.rb
85
+ - benchmarks/zmq_channel.rb
67
86
  - echo_client.rb
68
87
  - echo_server.rb
69
88
  - lib/zmachine.rb
70
89
  - lib/zmachine/acceptor.rb
71
90
  - lib/zmachine/channel.rb
72
91
  - lib/zmachine/connection.rb
92
+ - lib/zmachine/connection_manager.rb
73
93
  - lib/zmachine/deferrable.rb
74
94
  - lib/zmachine/hashed_wheel.rb
75
95
  - lib/zmachine/jeromq-0.3.0-SNAPSHOT.jar
@@ -77,34 +97,42 @@ files:
77
97
  - lib/zmachine/tcp_channel.rb
78
98
  - lib/zmachine/timers.rb
79
99
  - lib/zmachine/zmq_channel.rb
100
+ - spec/connection_manager_spec.rb
101
+ - spec/connection_spec.rb
80
102
  - spec/hashed_wheel_spec.rb
81
103
  - spec/spec_helper.rb
104
+ - spec/tcp_channel_spec.rb
105
+ - spec/zmq_channel_spec.rb
82
106
  - zmachine.gemspec
83
107
  homepage: https://github.com/madvertise/zmachine
84
108
  licenses:
85
109
  - MIT
86
110
  metadata: {}
87
- post_install_message:
111
+ post_install_message:
88
112
  rdoc_options: []
89
113
  require_paths:
90
114
  - lib
91
115
  required_ruby_version: !ruby/object:Gem::Requirement
92
116
  requirements:
93
- - - ! '>='
117
+ - - '>='
94
118
  - !ruby/object:Gem::Version
95
119
  version: '0'
96
120
  required_rubygems_version: !ruby/object:Gem::Requirement
97
121
  requirements:
98
- - - ! '>='
122
+ - - '>='
99
123
  - !ruby/object:Gem::Version
100
124
  version: '0'
101
125
  requirements: []
102
- rubyforge_project:
103
- rubygems_version: 2.0.6
104
- signing_key:
126
+ rubyforge_project:
127
+ rubygems_version: 2.1.9
128
+ signing_key:
105
129
  specification_version: 4
106
130
  summary: pure JRuby multi-threaded mostly EventMachine compatible event loop
107
131
  test_files:
132
+ - spec/connection_manager_spec.rb
133
+ - spec/connection_spec.rb
108
134
  - spec/hashed_wheel_spec.rb
109
135
  - spec/spec_helper.rb
110
- has_rdoc:
136
+ - spec/tcp_channel_spec.rb
137
+ - spec/zmq_channel_spec.rb
138
+ has_rdoc: