synapse 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  [![Build Status](https://travis-ci.org/airbnb/synapse.png?branch=master)](https://travis-ci.org/airbnb/synapse)
2
- [![Inline docs](http://inch-pages.github.io/github/airbnb/synapse.png)](http://inch-pages.github.io/github/airbnb/synapse)
2
+ [![Inline docs](http://inch-ci.org/github/airbnb/synapse.png)](http://inch-ci.org/github/airbnb/synapse)
3
3
 
4
4
  # Synapse #
5
5
 
data/lib/synapse.rb CHANGED
@@ -23,6 +23,12 @@ module Synapse
23
23
 
24
24
  # configuration is initially enabled to configure on first loop
25
25
  @config_updated = true
26
+
27
+ # Any exceptions in the watcher threads should wake the main thread so
28
+ # that we can fail fast.
29
+ Thread.abort_on_exception = true
30
+
31
+ log.debug "synapse: completed init"
26
32
  end
27
33
 
28
34
  # start all the watchers and enable haproxy configuration
@@ -70,6 +70,7 @@ module Synapse
70
70
  "option splice-response",
71
71
  "option srvtcpka",
72
72
  "option ssl-hello-chk",
73
+ "option tcp-check",
73
74
  "option tcp-smart-connect",
74
75
  "option tcpka",
75
76
  "option tcplog",
@@ -121,6 +122,10 @@ module Synapse
121
122
  "stick store-request",
122
123
  "stick store-response",
123
124
  "stick-table",
125
+ "tcp-check connect",
126
+ "tcp-check expect",
127
+ "tcp-check send",
128
+ "tcp-check send-binary",
124
129
  "tcp-request content",
125
130
  "tcp-request inspect-delay",
126
131
  "tcp-response content",
@@ -203,6 +208,7 @@ module Synapse
203
208
  "option splice-response",
204
209
  "option srvtcpka",
205
210
  "option ssl-hello-chk",
211
+ "option tcp-check",
206
212
  "option tcp-smart-accept",
207
213
  "option tcp-smart-connect",
208
214
  "option tcpka",
@@ -415,6 +421,7 @@ module Synapse
415
421
  "option splice-response",
416
422
  "option srvtcpka",
417
423
  "option ssl-hello-chk",
424
+ "option tcp-check",
418
425
  "option tcp-smart-accept",
419
426
  "option tcp-smart-connect",
420
427
  "option tcpka",
@@ -468,6 +475,10 @@ module Synapse
468
475
  "stick store-request",
469
476
  "stick store-response",
470
477
  "stick-table",
478
+ "tcp-check connect",
479
+ "tcp-check expect",
480
+ "tcp-check send",
481
+ "tcp-check send-binary",
471
482
  "tcp-request connection",
472
483
  "tcp-request content",
473
484
  "tcp-request inspect-delay",
@@ -7,31 +7,26 @@ module Synapse
7
7
  NUMBERS_RE = /^\d+$/
8
8
 
9
9
  def start
10
- zk_hosts = @discovery['hosts'].shuffle.join(',')
10
+ @zk_hosts = @discovery['hosts'].shuffle.join(',')
11
11
 
12
- log.info "synapse: starting ZK watcher #{@name} @ hosts: #{zk_hosts}, path: #{@discovery['path']}"
13
- @should_exit = false
14
- @zk = ZK.new(zk_hosts)
12
+ @watcher = nil
13
+ @zk = nil
15
14
 
16
- # call the callback to bootstrap the process
17
- watcher_callback.call
15
+ log.info "synapse: starting ZK watcher #{@name} @ hosts: #{@zk_hosts}, path: #{@discovery['path']}"
16
+ zk_connect
18
17
  end
19
18
 
20
19
  def stop
21
20
  log.warn "synapse: zookeeper watcher exiting"
22
-
23
- @should_exit = true
24
- @watcher.unsubscribe if defined? @watcher
25
- @zk.close! if defined? @zk
26
-
27
- log.info "synapse: zookeeper watcher cleaned up successfully"
21
+ zk_cleanup
28
22
  end
29
23
 
30
24
  def ping?
31
- @zk.ping?
25
+ @zk && @zk.connected?
32
26
  end
33
27
 
34
28
  private
29
+
35
30
  def validate_discovery_opts
36
31
  raise ArgumentError, "invalid discovery method #{@discovery['method']}" \
37
32
  unless @discovery['method'] == 'zookeeper'
@@ -44,6 +39,7 @@ module Synapse
44
39
  # helper method that ensures that the discovery path exists
45
40
  def create(path)
46
41
  log.debug "synapse: creating ZK path: #{path}"
42
+
47
43
  # recurse if the parent node does not exist
48
44
  create File.dirname(path) unless @zk.exists? File.dirname(path)
49
45
  @zk.create(path, ignore: :node_exists)
@@ -54,29 +50,23 @@ module Synapse
54
50
  log.info "synapse: discovering backends for service #{@name}"
55
51
 
56
52
  new_backends = []
57
- begin
58
- @zk.children(@discovery['path'], :watch => true).each do |id|
59
- node = @zk.get("#{@discovery['path']}/#{id}")
60
-
61
- begin
62
- host, port, name = deserialize_service_instance(node.first)
63
- rescue StandardError => e
64
- log.error "synapse: invalid data in ZK node #{id} at #{@discovery['path']}: #{e}"
65
- else
66
- server_port = @server_port_override ? @server_port_override : port
67
-
68
- # find the numberic id in the node name; used for leader elections if enabled
69
- numeric_id = id.split('_').last
70
- numeric_id = NUMBERS_RE =~ numeric_id ? numeric_id.to_i : nil
71
-
72
- log.debug "synapse: discovered backend #{name} at #{host}:#{server_port} for service #{@name}"
73
- new_backends << { 'name' => name, 'host' => host, 'port' => server_port, 'id' => numeric_id}
74
- end
53
+ @zk.children(@discovery['path'], :watch => true).each do |id|
54
+ node = @zk.get("#{@discovery['path']}/#{id}")
55
+
56
+ begin
57
+ host, port, name = deserialize_service_instance(node.first)
58
+ rescue StandardError => e
59
+ log.error "synapse: invalid data in ZK node #{id} at #{@discovery['path']}: #{e}"
60
+ else
61
+ server_port = @server_port_override ? @server_port_override : port
62
+
63
+ # find the numberic id in the node name; used for leader elections if enabled
64
+ numeric_id = id.split('_').last
65
+ numeric_id = NUMBERS_RE =~ numeric_id ? numeric_id.to_i : nil
66
+
67
+ log.debug "synapse: discovered backend #{name} at #{host}:#{server_port} for service #{@name}"
68
+ new_backends << { 'name' => name, 'host' => host, 'port' => server_port, 'id' => numeric_id}
75
69
  end
76
- rescue ZK::Exceptions::NoNode
77
- # the path must exist, otherwise watch callbacks will not work
78
- create(@discovery['path'])
79
- retry
80
70
  end
81
71
 
82
72
  if new_backends.empty?
@@ -94,10 +84,16 @@ module Synapse
94
84
 
95
85
  # sets up zookeeper callbacks if the data at the discovery path changes
96
86
  def watch
97
- return if @should_exit
87
+ return if @zk.nil?
98
88
 
99
- @watcher.unsubscribe if defined? @watcher
89
+ @watcher.unsubscribe unless @watcher.nil?
100
90
  @watcher = @zk.register(@discovery['path'], &watcher_callback)
91
+
92
+ # Verify that we actually set up the watcher.
93
+ unless @zk.exists?(@discovery['path'], :watch => true)
94
+ log.error "synapse: zookeeper watcher path #{@discovery['path']} does not exist!"
95
+ raise RuntimeError.new('could not set a ZK watch on a node that should exist')
96
+ end
101
97
  end
102
98
 
103
99
  # handles the event that a watched path has changed in zookeeper
@@ -112,6 +108,36 @@ module Synapse
112
108
  end
113
109
  end
114
110
 
111
+ def zk_cleanup
112
+ log.info "synapse: zookeeper watcher cleaning up"
113
+
114
+ @watcher.unsubscribe unless @watcher.nil?
115
+ @watcher = nil
116
+
117
+ @zk.close! unless @zk.nil?
118
+ @zk = nil
119
+
120
+ log.info "synapse: zookeeper watcher cleaned up successfully"
121
+ end
122
+
123
+ def zk_connect
124
+ log.info "synapse: zookeeper watcher connecting to ZK at #{@zk_hosts}"
125
+ @zk = ZK.new(@zk_hosts)
126
+
127
+ # handle session expiry -- by cleaning up zk, this will make `ping?`
128
+ # fail and so synapse will exit
129
+ @zk.on_expired_session do
130
+ log.warn "synapse: zookeeper watcher ZK session expired!"
131
+ zk_cleanup
132
+ end
133
+
134
+ # the path must exist, otherwise watch callbacks will not work
135
+ create(@discovery['path'])
136
+
137
+ # call the callback to bootstrap the process
138
+ watcher_callback.call
139
+ end
140
+
115
141
  # decode the data at a zookeeper endpoint
116
142
  def deserialize_service_instance(data)
117
143
  log.debug "synapse: deserializing process data"
@@ -1,3 +1,3 @@
1
1
  module Synapse
2
- VERSION = "0.10.0"
2
+ VERSION = "0.11.0"
3
3
  end
data/synapse.gemspec CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
16
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
 
19
- gem.add_runtime_dependency "zk", "~> 1.9.2"
19
+ gem.add_runtime_dependency "zk", "~> 1.9.4"
20
20
  gem.add_runtime_dependency "docker-api", "~> 1.7.2"
21
21
 
22
22
  gem.add_development_dependency "rake"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: synapse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-07 00:00:00.000000000 Z
12
+ date: 2014-06-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: zk
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 1.9.2
21
+ version: 1.9.4
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 1.9.2
29
+ version: 1.9.4
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: docker-api
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -162,18 +162,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
162
162
  - - ! '>='
163
163
  - !ruby/object:Gem::Version
164
164
  version: '0'
165
- segments:
166
- - 0
167
- hash: 2945433216079037469
168
165
  required_rubygems_version: !ruby/object:Gem::Requirement
169
166
  none: false
170
167
  requirements:
171
168
  - - ! '>='
172
169
  - !ruby/object:Gem::Version
173
170
  version: '0'
174
- segments:
175
- - 0
176
- hash: 2945433216079037469
177
171
  requirements: []
178
172
  rubyforge_project:
179
173
  rubygems_version: 1.8.23