zoo-service-discovery 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YTlmOWI4ZGM5YzM0NWExNWMyZDA5NDExYzRlN2NhNGYzZWI1YjY3OA==
4
+ MzEyY2YzNDY0ZWI5ODY1OTkzYjVlMzgyMmM1NjJiZGY5Y2NiNjk1ZA==
5
5
  data.tar.gz: !binary |-
6
- ZGM1YTJiOWRkZDhlMDBiZjRlMzNiNWQ0MDhiMDJiZDMyNTRiZDUwMA==
6
+ ZTY1YjJkMzc2ZjA0NmQzMjgwZmQ4NGM2ZWVjYjkyNWIyOTgzYTg2NA==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ZjA2OGI2OGVhYzM1NjUyODE4MDk4MjJlNGY2Y2ZkNTIxZDQ2MGIzODhiMTUw
10
- M2UyNWJmMWIzZjI0MDM5YmZjNzEzMmFkMzEyZWU3NDU0Yjg3MmY5MDA1Yzdi
11
- MmRmZmZiZTc0NTczYThhNWIyNTkxZjU5ZjgxNzIzMWMwZDhlODM=
9
+ OGU3NmM0ODYwNGQ4N2VjNzAyMDY5ZjhiNzdlOWZjZWFkNjliN2FkYzMyM2Rj
10
+ MWU5ZDllYzBlMGJlYTZlNzZkOTdlZjAxMTkwODY2MDYwMGRhMWIzNmI1MzYz
11
+ YTAzZDY1MDI0ZmE5NjY2NTFjMWU1NjFmN2I5YjMzM2FjMGI0NDE=
12
12
  data.tar.gz: !binary |-
13
- NGQ2YTNhMjFhMTYyZWUxNDM2ZmRjZjg4MGYzYWMxZDBmNWQwY2QxYjFlMWE0
14
- ODdmZjI2MjQ3NzE0YTIyMGRhODAzMTI2Mzk5MmRhZjAyYjAyZWVmODAxY2Yw
15
- OTA3YTRiZTRiNzQ5MTMxMzczNWJjYzJjMzEzODU1NDc5Yjc2NWQ=
13
+ MGZlZGM5NmZjMDU4M2NkYTIzODkyYzZjMDQ3OGU5OTZjZTI3NGY2MzlmM2Rk
14
+ YjViOGRkZjk4N2NjMzBhMDFhNmExMzFjZDYyOTM1YTcyMDRhZGFhM2NiYzUw
15
+ NTdjNDQ2Nzg0ZjJmOTQ2MjM4OGY3NzQyNDBhM2IwYzMxMzZmYzc=
@@ -1,2 +1,3 @@
1
1
  require_relative 'zoo_service/discovery'
2
2
  require_relative 'zoo_service/publication'
3
+ require_relative 'zoo_service/client_factory'
@@ -4,42 +4,39 @@ require 'zk'
4
4
  module ZooService
5
5
 
6
6
  # Performs service discovery for a HTTP service consumer.
7
- class Discovery
8
- class << self
9
- # :call-seq:
10
- # get_service_url(name) => String
11
- #
12
- # Gets service URL by _name_.
13
- #
14
- # Returns service URL, if everything went OK, +nil+ otherwise.
15
- def get_service_url(name)
16
- get_published_urls(name).first
17
- end
18
-
19
- protected
20
-
21
- # Gets published URLs of _service_name_.
22
- def get_published_urls(service_name)
23
- service_path = "/services/#{service_name}"
24
- publications = zk.children(service_path, ignore: :no_node) || [ ]
7
+ class DiscoveryImpl
8
+
9
+ # :call-seq:
10
+ # get_service_url(name) => String
11
+ #
12
+ # Gets service URL by _name_.
13
+ #
14
+ # Returns service URL, if everything went OK, +nil+ otherwise.
15
+ def get_service_url(name)
16
+ get_published_urls(name).first
17
+ end
25
18
 
26
- unless publications.empty?
27
- zk.get("#{service_path}/#{publications.last}", ignore: :no_node)
28
- else
29
- [ ]
30
- end
31
- end
19
+ protected
32
20
 
33
- # Returns a working instance of a ZooKeeper client.
34
- def zk
35
- if Thread.current[:service_discovery_zk_client]
36
- return Thread.current[:service_discovery_zk_client]
37
- end
21
+ # Gets published URLs of _service_name_.
22
+ def get_published_urls(service_name)
23
+ service_path = "/services/#{service_name}"
24
+ publications = zk.children(service_path, ignore: :no_node) || [ ]
38
25
 
39
- Thread.current[:service_discovery_zk_client] ||= ZK.new(ENV['SERVICE_DISCOVERY_WELLKNOWN_ADDRESS'] || 'localhost:2181')
26
+ unless publications.empty?
27
+ zk.get("#{service_path}/#{publications.last}", ignore: :no_node)
28
+ else
29
+ [ ]
40
30
  end
31
+ end
41
32
 
33
+ # Returns a working instance of a ZooKeeper client.
34
+ def zk
35
+ @zk ||= ZK.new(ENV['SERVICE_DISCOVERY_WELLKNOWN_ADDRESS'] || 'localhost:2181')
42
36
  end
37
+
43
38
  end
44
39
 
40
+ Discovery = DiscoveryImpl.new
41
+
45
42
  end
@@ -4,56 +4,64 @@ require 'zk'
4
4
  module ZooService
5
5
 
6
6
  # Performs service publication for a HTTP service provider.
7
- class Publication
8
- class << self
9
- # :call-seq:
10
- # register_service(name, url) => Boolean
11
- #
12
- # Registers a well-known service with _name_ at _url_.
13
- #
14
- # Returns +true+, if everything went OK, +false+ otherwise.
15
- def register_service(name, url)
16
- registration_block = create_registration_block(name, url)
17
- service_registration_blocks << registration_block
18
- registration_block.(zk)
7
+ class PublicationImpl
8
+
9
+ def initialize(phusion_passenger = nil)
10
+ return unless phusion_passenger
11
+ phusion_passenger.on_event(:starting_worker_process) do |forked|
12
+ if forked
13
+ reconnect
14
+ end
19
15
  end
16
+ end
20
17
 
21
- protected
18
+ # :call-seq:
19
+ # register_service(name, url) => Boolean
20
+ #
21
+ # Registers a well-known service with _name_ at _url_.
22
+ #
23
+ # Returns +true+, if everything went OK, +false+ otherwise.
24
+ def register_service(name, url)
25
+ registration_block = create_registration_block(name, url)
26
+ service_registration_blocks << registration_block
27
+ registration_block.(zk)
28
+ end
22
29
 
23
- # Creates a lambda that once called registeres the service on the URL.
24
- def create_registration_block(name, url)
25
- -> zk {
26
- service_path = "/services/#{name}"
27
- zk.mkdir_p(service_path) unless zk.exists?(service_path)
28
- zk.create("#{service_path}/node-", url, mode: :ephemeral_sequential)
29
- }
30
- end
30
+ def reconnect
31
+ @zk = nil
32
+ zk
33
+ end
31
34
 
32
- # Stores the registration blocks that are rerun after reconnection to
33
- # the ZooKeeper.
34
- def service_registration_blocks
35
- @service_registration_blocks ||= [ ]
36
- end
35
+ protected
37
36
 
38
- # Returns a working instance of a ZooKeeper client.
39
- def zk
40
- if Thread.current[:service_publication_zk_client]
41
- return Thread.current[:service_publication_zk_client]
42
- end
37
+ # Creates a lambda that once called registeres the service on the URL.
38
+ def create_registration_block(name, url)
39
+ -> zk {
40
+ service_path = "/services/#{name}"
41
+ zk.mkdir_p(service_path) unless zk.exists?(service_path)
42
+ zk.create("#{service_path}/node-", url, mode: :ephemeral_sequential)
43
+ }
44
+ end
45
+
46
+ # Stores the registration blocks that are rerun after reconnection to
47
+ # the ZooKeeper.
48
+ def service_registration_blocks
49
+ @service_registration_blocks ||= [ ]
50
+ end
43
51
 
44
- zk_client = ZK.new(ENV['SERVICE_DISCOVERY_WELLKNOWN_ADDRESS'] || 'localhost:2181') do |zk|
45
- zk.on_connected do
46
- # Rerun all the registrations upon reconnection
47
- service_registration_blocks.each do |registration_block|
48
- registration_block.(zk)
49
- end
52
+ # Returns a working instance of a ZooKeeper client.
53
+ def zk
54
+ @zk ||= ZK.new(ENV['SERVICE_DISCOVERY_WELLKNOWN_ADDRESS'] || 'localhost:2181') do |zk|
55
+ zk.on_connected do
56
+ # Rerun all the registrations upon reconnection
57
+ service_registration_blocks.each do |registration_block|
58
+ registration_block.(zk)
50
59
  end
51
60
  end
52
-
53
- Thread.current[:service_publication_zk_client] = zk_client
54
61
  end
55
-
56
62
  end
63
+
57
64
  end
58
65
 
66
+ Publication = defined?(PhusionPassenger) ? PublicationImpl.new(PhusionPassenger) : PublicationImpl.new
59
67
  end
@@ -4,41 +4,30 @@ describe "Discovered service URL (registered in a separate process)" do
4
4
 
5
5
  def kill_server_process
6
6
  begin
7
- Process.kill("HUP", server_process)
7
+ Process.kill("KILL", server_process)
8
8
  Process.wait(server_process)
9
9
  rescue Errno::ESRCH
10
10
  # ignore
11
11
  end
12
12
  end
13
13
 
14
- before {
15
- if Thread.current[:service_discovery_zk_client]
16
- Thread.current[:service_discovery_zk_client].close
17
- Thread.current[:service_discovery_zk_client] = nil
18
- end
19
-
20
- if Thread.current[:service_publication_zk_client]
21
- Thread.current[:service_publication_zk_client].close
22
- Thread.current[:service_publication_zk_client] = nil
23
- end
24
- }
25
-
26
14
  subject {
27
- ZooService::Discovery.get_service_url(service)
15
+ ZooService::DiscoveryImpl.new.get_service_url(service)
28
16
  }
29
17
 
30
18
  let(:real_service_url) {
31
19
  "http://sample.dev/"
32
20
  }
33
21
 
34
- let(:service) {
35
- "service"
22
+ let!(:service) {
23
+ "service%4.4d%4.4d" % [ rand(9999), rand(9999) ]
36
24
  }
37
25
 
38
26
  let!(:server_process) {
39
27
  pid = fork do |variable|
40
- ZooService::Publication.register_service(service, real_service_url)
41
- sleep 1 while true
28
+ ZooService::PublicationImpl.new.register_service(service, real_service_url)
29
+ sleep 60 # fail safely after 60 secs
30
+ exit
42
31
  end
43
32
  sleep 0.5
44
33
  return pid
@@ -57,11 +46,10 @@ describe "Discovered service URL (registered in a separate process)" do
57
46
  end
58
47
 
59
48
  it "retains value when ZooKeeper fails and restarts with an empty DB" do
60
- should == real_service_url
61
-
62
49
  ZookeeperRunner.clean
63
50
  ZookeeperRunner.stop
64
51
  ZookeeperRunner.start
52
+ sleep 10
65
53
 
66
54
  should == real_service_url
67
55
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe "Discovered service URL" do
4
4
 
5
5
  subject {
6
- ZooService::Discovery.get_service_url(service)
6
+ ZooService::DiscoveryImpl.new.get_service_url(service)
7
7
  }
8
8
 
9
9
  let(:real_service_url) {
@@ -13,7 +13,7 @@ describe "Discovered service URL" do
13
13
  context "when service is registered" do
14
14
 
15
15
  let!(:service) {
16
- ZooService::Publication.register_service("service", real_service_url)
16
+ ZooService::PublicationImpl.new.register_service("service", real_service_url)
17
17
  "service"
18
18
  }
19
19
 
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ class PhusionPassenger
4
+ class << self
5
+ def on_event(event, &block)
6
+ @events ||= {}
7
+ @events[event] = block
8
+ end
9
+
10
+ def start
11
+ fork do
12
+ # Phusion Passenger user request handler
13
+ @events[:starting_worker_process].call(true)
14
+ sleep 10
15
+ exit
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ describe "Publication service" do
22
+
23
+ describe "when started on Passenger" do
24
+ let!(:service) {
25
+ "service%4.4d%4.4d" % [ rand(9999), rand(9999) ]
26
+ }
27
+
28
+ let(:url) {
29
+ "http://pornhub.com/"
30
+ }
31
+
32
+ subject {
33
+ ZooService::DiscoveryImpl.new.get_service_url(service)
34
+ }
35
+
36
+ before do
37
+ fork do
38
+ # Phusion Passenger starter
39
+ ZooService::PublicationImpl.new(PhusionPassenger).register_service(service, url)
40
+ PhusionPassenger.start
41
+ exit
42
+ end
43
+
44
+ sleep 1 # we love sleeping in these tests
45
+ end
46
+
47
+ it { should == url }
48
+ end
49
+
50
+
51
+ describe "when started on other(non-Passenger) server" do
52
+ it "should not reconnect" do
53
+ expect(ZooService::PublicationImpl.new).not_to receive(:reconnect)
54
+ end
55
+ end
56
+
57
+ end
@@ -2,13 +2,15 @@ class ZookeeperRunner
2
2
  class << self
3
3
 
4
4
  def start
5
- system "zkServer start > /dev/null 2>&1"
6
- wait_zookeeper_start
5
+ until `zkServer start 2>&1`.include?("already running")
6
+ sleep 1
7
+ end
7
8
  end
8
9
 
9
10
  def stop
10
- system "zkServer stop > /dev/null 2>&1"
11
- wait_zookeeper_stop
11
+ until `zkServer stop 2>&1`.include?("no zookeeper to stop")
12
+ sleep 1
13
+ end
12
14
  end
13
15
 
14
16
  def clean
@@ -17,20 +19,5 @@ class ZookeeperRunner
17
19
  end
18
20
  end
19
21
 
20
- protected
21
-
22
- def wait_zookeeper_start
23
- sleep 1 while zookeeper_pid == 0
24
- end
25
-
26
- def wait_zookeeper_stop
27
- sleep 0.125 while zookeeper_pid > 0
28
- end
29
-
30
- def zookeeper_pid
31
- `ps aux | grep zookeeper | grep java | grep -v grep | awk '{ print $2; }'`.to_i
32
- end
33
-
34
-
35
22
  end
36
23
  end
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zoo-service-discovery
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Druzhinin <andrey.druginin@gmail.com>
8
+ - Ramil Gilmanov <ramil1985@mail.ru>
8
9
  - Ivan Kasatenko <sky@uniqsystems.ru>
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2013-10-04 00:00:00.000000000 Z
13
+ date: 2013-12-27 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: zk
@@ -36,6 +37,7 @@ files:
36
37
  - lib/zoo_service/publication.rb
37
38
  - spec/features/complex_discovery_spec.rb
38
39
  - spec/features/discovery_spec.rb
40
+ - spec/features/passenger_spec.rb
39
41
  - spec/spec_helper.rb
40
42
  - spec/support/zookeeper_runner.rb
41
43
  - README.md