einhorn 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,89 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../test_helper'))
2
+
3
+ require 'set'
4
+ require 'einhorn'
5
+
6
+ module Einhorn::Event
7
+ def self.reset
8
+ @@loopbreak_reader = nil
9
+ @@loopbreak_writer = nil
10
+ @@readable = {}
11
+ @@writeable = {}
12
+ @@timers = {}
13
+ end
14
+ end
15
+
16
+ class EventTest < Test::Unit::TestCase
17
+ context "when run the event loop" do
18
+ setup do
19
+ Einhorn::Event.reset
20
+ end
21
+
22
+ teardown do
23
+ Einhorn::Event.reset
24
+ end
25
+
26
+ should "select on readable descriptors" do
27
+ sock1 = mock(:fileno => 4)
28
+ sock2 = mock(:fileno => 5)
29
+
30
+ conn1 = Einhorn::Event::Connection.open(sock1)
31
+ conn2 = Einhorn::Event::Connection.open(sock2)
32
+
33
+ IO.expects(:select).once.with do |readers, writers, errs, timeout|
34
+ Set.new(readers) == Set.new([sock1, sock2]) &&
35
+ writers == [] &&
36
+ errs == nil &&
37
+ timeout == nil
38
+ end.returns([[], [], []])
39
+
40
+ Einhorn::Event.loop_once
41
+ end
42
+
43
+ should "select on writeable descriptors" do
44
+ sock1 = mock(:fileno => 4)
45
+ sock2 = mock(:fileno => 5)
46
+
47
+ conn1 = Einhorn::Event::Connection.open(sock1)
48
+ conn2 = Einhorn::Event::Connection.open(sock2)
49
+
50
+ sock2.expects(:write_nonblock).once.raises(Errno::EWOULDBLOCK.new)
51
+ conn2.write('Hello!')
52
+
53
+ IO.expects(:select).once.with do |readers, writers, errs, timeout|
54
+ Set.new(readers) == Set.new([sock1, sock2]) &&
55
+ writers == [sock2] &&
56
+ errs == nil &&
57
+ timeout == nil
58
+ end.returns([[], [], []])
59
+
60
+ Einhorn::Event.loop_once
61
+ end
62
+
63
+ should "run callbacks for ready selectables" do
64
+ sock1 = mock(:fileno => 4)
65
+ sock2 = mock(:fileno => 5)
66
+
67
+ conn1 = Einhorn::Event::Connection.open(sock1)
68
+ conn2 = Einhorn::Event::Connection.open(sock2)
69
+
70
+ sock2.expects(:write_nonblock).once.raises(Errno::EWOULDBLOCK.new)
71
+ conn2.write('Hello!')
72
+
73
+ IO.expects(:select).once.with do |readers, writers, errs, timeout|
74
+ Set.new(readers) == Set.new([sock1, sock2]) &&
75
+ writers == [sock2] &&
76
+ errs == nil &&
77
+ timeout == nil
78
+ end.returns([[sock1], [sock2], []])
79
+
80
+ conn1.expects(:notify_readable).once
81
+ conn2.expects(:notify_writeable).never
82
+
83
+ conn1.expects(:notify_readable).never
84
+ conn2.expects(:notify_writeable).once
85
+
86
+ Einhorn::Event.loop_once
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../test_helper'))
2
+
3
+ require 'einhorn'
4
+
5
+ class EinhornTest < Test::Unit::TestCase
6
+ context "when sockifying" do
7
+ teardown do
8
+ Einhorn::State.sockets = {}
9
+ end
10
+
11
+ should "correctly parse srv: arguments" do
12
+ cmd = ['foo', 'srv:1.2.3.4:123,llama,test', 'bar']
13
+ Einhorn.expects(:bind).once.with('1.2.3.4', '123', ['llama', 'test']).returns(4)
14
+
15
+ Einhorn.socketify!(cmd)
16
+
17
+ assert_equal(['foo', '4', 'bar'], cmd)
18
+ end
19
+
20
+ should "correctly parse --opt=srv: arguments" do
21
+ cmd = ['foo', '--opt=srv:1.2.3.4:456', 'baz']
22
+ Einhorn.expects(:bind).once.with('1.2.3.4', '456', []).returns(5)
23
+
24
+ Einhorn.socketify!(cmd)
25
+
26
+ assert_equal(['foo', '--opt=5', 'baz'], cmd)
27
+ end
28
+
29
+ should "use the same fd number for the same server spec" do
30
+ cmd = ['foo', '--opt=srv:1.2.3.4:8910', 'srv:1.2.3.4:8910']
31
+ Einhorn.expects(:bind).once.with('1.2.3.4', '8910', []).returns(10)
32
+
33
+ Einhorn.socketify!(cmd)
34
+
35
+ assert_equal(['foo', '--opt=10', '10'], cmd)
36
+ end
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: einhorn
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
+ platform: ruby
12
+ authors:
13
+ - Greg Brockman
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-05-29 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: json
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: shoulda
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: mocha
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ type: :development
61
+ version_requirements: *id003
62
+ description: Einhorn makes it easy to run multiple instances of an application server, all listening on the same port. You can also seamlessly restart your workers without dropping any requests. Einhorn requires minimal application-level support, making it easy to use with an existing project.
63
+ email:
64
+ - gdb@stripe.com
65
+ executables:
66
+ - einhorn
67
+ - einhornsh
68
+ extensions: []
69
+
70
+ extra_rdoc_files: []
71
+
72
+ files:
73
+ - .gitignore
74
+ - Gemfile
75
+ - LICENSE
76
+ - README.md
77
+ - README.md.in
78
+ - Rakefile
79
+ - bin/einhorn
80
+ - bin/einhornsh
81
+ - einhorn.gemspec
82
+ - example/pool_worker.rb
83
+ - example/thin_example
84
+ - example/time_server
85
+ - lib/einhorn.rb
86
+ - lib/einhorn/client.rb
87
+ - lib/einhorn/command.rb
88
+ - lib/einhorn/command/interface.rb
89
+ - lib/einhorn/event.rb
90
+ - lib/einhorn/event/abstract_text_descriptor.rb
91
+ - lib/einhorn/event/ack_timer.rb
92
+ - lib/einhorn/event/command_server.rb
93
+ - lib/einhorn/event/connection.rb
94
+ - lib/einhorn/event/loop_breaker.rb
95
+ - lib/einhorn/event/persistent.rb
96
+ - lib/einhorn/event/timer.rb
97
+ - lib/einhorn/version.rb
98
+ - lib/einhorn/worker.rb
99
+ - lib/einhorn/worker_pool.rb
100
+ - test/test_helper.rb
101
+ - test/unit/einhorn.rb
102
+ - test/unit/einhorn/command.rb
103
+ - test/unit/einhorn/command/interface.rb
104
+ - test/unit/einhorn/event.rb
105
+ homepage: https://github.com/stripe/einhorn
106
+ licenses: []
107
+
108
+ post_install_message:
109
+ rdoc_options: []
110
+
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ hash: 3
119
+ segments:
120
+ - 0
121
+ version: "0"
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ requirements: []
132
+
133
+ rubyforge_project:
134
+ rubygems_version: 1.8.21
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: "Einhorn: the language-independent shared socket manager"
138
+ test_files:
139
+ - test/test_helper.rb
140
+ - test/unit/einhorn.rb
141
+ - test/unit/einhorn/command.rb
142
+ - test/unit/einhorn/command/interface.rb
143
+ - test/unit/einhorn/event.rb