synapse 0.0.1 → 0.2.1
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.
- data/.gitignore +3 -0
- data/.rspec +2 -0
- data/Gemfile.lock +45 -0
- data/README.md +185 -4
- data/Vagrantfile +112 -0
- data/bin/synapse +54 -0
- data/chef/converge +4 -0
- data/chef/cookbooks/lxc/recipes/default.rb +2 -0
- data/chef/cookbooks/synapse/attributes/default.rb +1 -0
- data/chef/cookbooks/synapse/recipes/default.rb +6 -0
- data/chef/run.json +8 -0
- data/chef/run.rb +2 -0
- data/client/.RData +0 -0
- data/client/.Rhistory +294 -0
- data/client/bench_rewrite_config.dat +2013 -0
- data/client/benchmark-client.iml +20 -0
- data/client/pom.xml +45 -0
- data/client/src/main/java/ClientArsch.java +68 -0
- data/client/src/main/java/META-INF/MANIFEST.MF +3 -0
- data/config/synapse.conf.json +96 -0
- data/haproxy.pid +1 -0
- data/lib/gen-rb/endpoint_types.rb +65 -0
- data/lib/gen-rb/thrift.rb +65 -0
- data/lib/synapse/base.rb +5 -0
- data/lib/synapse/haproxy.rb +200 -0
- data/lib/synapse/service_watcher/base.rb +44 -0
- data/lib/synapse/service_watcher/dns.rb +98 -0
- data/lib/synapse/service_watcher/ec2tag.rb +26 -0
- data/lib/synapse/service_watcher/zookeeper.rb +138 -0
- data/lib/synapse/service_watcher.rb +28 -0
- data/lib/synapse/version.rb +1 -1
- data/lib/synapse.rb +61 -2
- data/spec/lib/synapse/haproxy_spec.rb +14 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/config.rb +9 -0
- data/spec/support/minimum.conf.yaml +27 -0
- data/synapse.gemspec +7 -0
- data/test.sh +3 -0
- metadata +123 -5
@@ -0,0 +1,98 @@
|
|
1
|
+
require_relative "./base"
|
2
|
+
|
3
|
+
require 'thread'
|
4
|
+
require 'resolv'
|
5
|
+
|
6
|
+
module Synapse
|
7
|
+
class DnsWatcher < BaseWatcher
|
8
|
+
def start
|
9
|
+
@check_interval = @discovery['check_interval'] || 30.0
|
10
|
+
@nameserver = @discovery['nameserver']
|
11
|
+
|
12
|
+
watch
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def validate_discovery_opts
|
17
|
+
raise ArgumentError, "invalid discovery method #{@discovery['method']}" \
|
18
|
+
unless @discovery['method'] == 'dns'
|
19
|
+
raise ArgumentError, "a non-empty list of servers is required" \
|
20
|
+
if @discovery['servers'].empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
def watch
|
24
|
+
@watcher = Thread.new do
|
25
|
+
last_resolution = resolve_servers
|
26
|
+
configure_backends(last_resolution)
|
27
|
+
while true
|
28
|
+
begin
|
29
|
+
start = Time.now
|
30
|
+
current_resolution = resolve_servers
|
31
|
+
unless last_resolution == current_resolution
|
32
|
+
last_resolution = current_resolution
|
33
|
+
configure_backends(last_resolution)
|
34
|
+
end
|
35
|
+
|
36
|
+
sleep_until_next_check(start)
|
37
|
+
rescue => e
|
38
|
+
log.warn "Error in watcher thread: #{e.inspect}"
|
39
|
+
log.warn e.backtrace
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def sleep_until_next_check(start_time)
|
46
|
+
sleep_time = @check_interval - (Time.now - start_time)
|
47
|
+
if sleep_time > 0.0
|
48
|
+
sleep(sleep_time)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def resolve_servers
|
53
|
+
resolver.tap do |dns|
|
54
|
+
resolution = @discovery['servers'].map do |server|
|
55
|
+
addresses = dns.getaddresses(server['host']).map(&:to_s)
|
56
|
+
[server, addresses.sort]
|
57
|
+
end
|
58
|
+
|
59
|
+
return resolution
|
60
|
+
end
|
61
|
+
rescue => e
|
62
|
+
log.warn "Error while resolving host names: #{e.inspect}"
|
63
|
+
[]
|
64
|
+
end
|
65
|
+
|
66
|
+
def resolver
|
67
|
+
args = [{:nameserver => @nameserver}] if @nameserver
|
68
|
+
Resolv::DNS.open(*args)
|
69
|
+
end
|
70
|
+
|
71
|
+
def configure_backends(servers)
|
72
|
+
new_backends = servers.flat_map do |(server, addresses)|
|
73
|
+
addresses.map do |address|
|
74
|
+
{
|
75
|
+
'name' => "#{server['name']}-#{[address, server['port']].hash}",
|
76
|
+
'host' => address,
|
77
|
+
'port' => server['port']
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
if new_backends.empty?
|
83
|
+
if @default_servers.empty?
|
84
|
+
log.warn "synapse: no backends and no default servers for service #{@name};" \
|
85
|
+
" using previous backends: #{@backends.inspect}"
|
86
|
+
else
|
87
|
+
log.warn "synapse: no backends for service #{@name};" \
|
88
|
+
" using default servers: #{@default_servers.inspect}"
|
89
|
+
@backends = @default_servers
|
90
|
+
end
|
91
|
+
else
|
92
|
+
log.info "synapse: discovered #{new_backends.length} backends for service #{@name}"
|
93
|
+
@backends = new_backends
|
94
|
+
end
|
95
|
+
@synapse.configure
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative "./base"
|
2
|
+
|
3
|
+
module Synapse
|
4
|
+
class EC2Watcher < BaseWatcher
|
5
|
+
def start
|
6
|
+
# connect to ec2
|
7
|
+
# find all servers whose @discovery['tag_name'] matches @discovery['tag_value']
|
8
|
+
# call @synapse.configure
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
def validate_discovery_opts
|
13
|
+
raise ArgumentError, "invalid discovery method #{@discovery['method']}" \
|
14
|
+
unless @discovery['method'] == 'ec2tag'
|
15
|
+
raise ArgumentError, "a `server_port_override` option is required for ec2tag watchers" \
|
16
|
+
unless @server_port_override
|
17
|
+
raise ArgumentError, "missing aws credentials for service #{@name}" \
|
18
|
+
unless (@discovery['aws_key'] && @discovery['aws_secret'])
|
19
|
+
raise ArgumentError, "aws tag name is required for service #{@name}" \
|
20
|
+
unless @discovery['tag_name']
|
21
|
+
raise ArgumentError, "aws tag value required for service #{@name}" \
|
22
|
+
unless @discovery['tag_value']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require_relative "./base"
|
2
|
+
|
3
|
+
require_relative "../../gen-rb/endpoint_types"
|
4
|
+
require_relative "../../gen-rb/thrift"
|
5
|
+
require 'zk'
|
6
|
+
|
7
|
+
module Synapse
|
8
|
+
class ZookeeperWatcher < BaseWatcher
|
9
|
+
def start
|
10
|
+
zk_hosts = @discovery['hosts'].shuffle.join(',')
|
11
|
+
|
12
|
+
log.info "synapse: starting ZK watcher #{@name} @ hosts: #{zk_hosts}, path: #{@discovery['path']}"
|
13
|
+
@zk = ZK.new(zk_hosts)
|
14
|
+
|
15
|
+
@deserializer = Thrift::Deserializer.new
|
16
|
+
|
17
|
+
watch
|
18
|
+
discover
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def validate_discovery_opts
|
23
|
+
raise ArgumentError, "invalid discovery method #{@discovery['method']}" \
|
24
|
+
unless @discovery['method'] == 'zookeeper'
|
25
|
+
raise ArgumentError, "missing or invalid zookeeper host for service #{@name}" \
|
26
|
+
unless @discovery['hosts']
|
27
|
+
raise ArgumentError, "invalid zookeeper path for service #{@name}" \
|
28
|
+
unless @discovery['path']
|
29
|
+
end
|
30
|
+
|
31
|
+
# helper method that ensures that the discovery path exists
|
32
|
+
def create(path)
|
33
|
+
log.debug "synapse: creating ZK path: #{path}"
|
34
|
+
# recurse if the parent node does not exist
|
35
|
+
create File.dirname(path) unless @zk.exists? File.dirname(path)
|
36
|
+
@zk.create(path, ignore: :node_exists)
|
37
|
+
end
|
38
|
+
|
39
|
+
# find the current backends at the discovery path; sets @backends
|
40
|
+
def discover
|
41
|
+
log.info "synapse: discovering backends for service #{@name}"
|
42
|
+
|
43
|
+
new_backends = []
|
44
|
+
begin
|
45
|
+
@zk.children(@discovery['path'], :watch => true).map do |name|
|
46
|
+
node = @zk.get("#{@discovery['path']}/#{name}")
|
47
|
+
|
48
|
+
begin
|
49
|
+
host, port = deserialize_service_instance(node.first)
|
50
|
+
rescue
|
51
|
+
log.error "synapse: invalid data in ZK node #{name} at #{@discovery['path']}"
|
52
|
+
else
|
53
|
+
server_port = @server_port_override ? @server_port_override : port
|
54
|
+
backend_name = "#{name}-#{[host, server_port].hash}"
|
55
|
+
|
56
|
+
log.debug "synapse: discovered backend #{backend_name} at #{host}:#{server_port} for service #{@name}"
|
57
|
+
new_backends << { 'name' => backend_name, 'host' => host, 'port' => server_port}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
rescue ZK::Exceptions::NoNode
|
61
|
+
# the path must exist, otherwise watch callbacks will not work
|
62
|
+
create(@discovery['path'])
|
63
|
+
retry
|
64
|
+
end
|
65
|
+
|
66
|
+
if new_backends.empty?
|
67
|
+
if @default_servers.empty?
|
68
|
+
log.warn "synapse: no backends and no default servers for service #{@name}; using previous backends: #{@backends.inspect}"
|
69
|
+
else
|
70
|
+
log.warn "synapse: no backends for service #{@name}; using default servers: #{@default_servers.inspect}"
|
71
|
+
@backends = @default_servers
|
72
|
+
end
|
73
|
+
else
|
74
|
+
log.info "synapse: discovered #{new_backends.length} backends for service #{@name}"
|
75
|
+
@backends = new_backends
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# sets up zookeeper callbacks if the data at the discovery path changes
|
80
|
+
def watch
|
81
|
+
@watcher.unsubscribe if defined? @watcher
|
82
|
+
@watcher = @zk.register(@discovery['path'], &watcher_callback)
|
83
|
+
end
|
84
|
+
|
85
|
+
# handles the event that a watched path has changed in zookeeper
|
86
|
+
def watcher_callback
|
87
|
+
Proc.new do |event|
|
88
|
+
# Set new watcher
|
89
|
+
watch
|
90
|
+
# Rediscover
|
91
|
+
discover
|
92
|
+
# send a message to calling class to reconfigure
|
93
|
+
@synapse.configure
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# tries to extract host/port from a json hash
|
98
|
+
def parse_json(data)
|
99
|
+
begin
|
100
|
+
json = JSON.parse data
|
101
|
+
rescue Object => o
|
102
|
+
return false
|
103
|
+
end
|
104
|
+
raise 'instance json data does not have host key' unless json.has_key?('host')
|
105
|
+
raise 'instance json data does not have port key' unless json.has_key?('port')
|
106
|
+
return json['host'], json['port']
|
107
|
+
end
|
108
|
+
|
109
|
+
# tries to extract a host/port from twitter thrift data
|
110
|
+
def parse_thrift(data)
|
111
|
+
begin
|
112
|
+
service = Twitter::Thrift::ServiceInstance.new
|
113
|
+
@deserializer.deserialize(service, data)
|
114
|
+
rescue Object => o
|
115
|
+
return false
|
116
|
+
end
|
117
|
+
raise "instance thrift data does not have host" if service.serviceEndpoint.host.nil?
|
118
|
+
raise "instance thrift data does not have port" if service.serviceEndpoint.port.nil?
|
119
|
+
return service.serviceEndpoint.host, service.serviceEndpoint.port
|
120
|
+
end
|
121
|
+
|
122
|
+
# decode the data at a zookeeper endpoint
|
123
|
+
def deserialize_service_instance(data)
|
124
|
+
log.debug "synapse: deserializing process data"
|
125
|
+
|
126
|
+
# first, lets try parsing this as thrift
|
127
|
+
host, port = parse_thrift(data)
|
128
|
+
return host, port if host
|
129
|
+
|
130
|
+
# if that does not work, try json
|
131
|
+
host, port = parse_json(data)
|
132
|
+
return host, port if host
|
133
|
+
|
134
|
+
# if we got this far, then we have a problem
|
135
|
+
raise "could not decode this data:\n#{data}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative "./service_watcher/base"
|
2
|
+
require_relative "./service_watcher/zookeeper"
|
3
|
+
require_relative "./service_watcher/ec2tag"
|
4
|
+
require_relative "./service_watcher/dns"
|
5
|
+
|
6
|
+
module Synapse
|
7
|
+
class ServiceWatcher
|
8
|
+
|
9
|
+
@watchers = {
|
10
|
+
'base'=>BaseWatcher,
|
11
|
+
'zookeeper'=>ZookeeperWatcher,
|
12
|
+
'ec2tag'=>EC2Watcher,
|
13
|
+
'dns' => DnsWatcher
|
14
|
+
}
|
15
|
+
|
16
|
+
# the method which actually dispatches watcher creation requests
|
17
|
+
def self.create(opts, synapse)
|
18
|
+
raise ArgumentError, "Missing discovery method when trying to create watcher" \
|
19
|
+
unless opts.has_key?('discovery') && opts['discovery'].has_key?('method')
|
20
|
+
|
21
|
+
discovery_method = opts['discovery']['method']
|
22
|
+
raise ArgumentError, "Invalid discovery method #{discovery_method}" \
|
23
|
+
unless @watchers.has_key?(discovery_method)
|
24
|
+
|
25
|
+
return @watchers[discovery_method].new(opts, synapse)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/synapse/version.rb
CHANGED
data/lib/synapse.rb
CHANGED
@@ -1,5 +1,64 @@
|
|
1
|
-
|
1
|
+
require_relative "synapse/version"
|
2
|
+
require_relative "synapse/base"
|
3
|
+
require_relative "synapse/haproxy"
|
4
|
+
require_relative "synapse/service_watcher"
|
5
|
+
|
6
|
+
require 'logger'
|
7
|
+
require 'json'
|
8
|
+
|
9
|
+
include Synapse
|
2
10
|
|
3
11
|
module Synapse
|
4
|
-
|
12
|
+
class Synapse
|
13
|
+
def initialize(opts={})
|
14
|
+
# disable configuration until this is started
|
15
|
+
@configure_enabled = false
|
16
|
+
|
17
|
+
# create the service watchers for all our services
|
18
|
+
raise "specify a list of services to connect in the config" unless opts.has_key?('services')
|
19
|
+
@service_watchers = create_service_watchers(opts['services'])
|
20
|
+
|
21
|
+
# create the haproxy object
|
22
|
+
raise "haproxy config section is missing" unless opts.has_key?('haproxy')
|
23
|
+
@haproxy = Haproxy.new(opts['haproxy'])
|
24
|
+
end
|
25
|
+
|
26
|
+
# start all the watchers and enable haproxy configuration
|
27
|
+
def run
|
28
|
+
log.info "synapse: starting..."
|
29
|
+
|
30
|
+
@service_watchers.map { |watcher| watcher.start }
|
31
|
+
@configure_enabled = true
|
32
|
+
configure
|
33
|
+
|
34
|
+
# loop forever
|
35
|
+
loops = 0
|
36
|
+
loop do
|
37
|
+
sleep 1
|
38
|
+
loops += 1
|
39
|
+
log.debug "synapse: still running at #{Time.now}" if (loops % 60) == 0
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# reconfigure haproxy based on our watchers
|
44
|
+
def configure
|
45
|
+
if @configure_enabled
|
46
|
+
log.info "synapse: regenerating haproxy config"
|
47
|
+
@haproxy.update_config(@service_watchers)
|
48
|
+
else
|
49
|
+
log.info "synapse: reconfigure requested, but it's not yet enabled"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def create_service_watchers(services={})
|
55
|
+
service_watchers =[]
|
56
|
+
services.each do |service_config|
|
57
|
+
service_watchers << ServiceWatcher.create(service_config, self)
|
58
|
+
end
|
59
|
+
|
60
|
+
return service_watchers
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
5
64
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class MockWatcher; end;
|
4
|
+
|
5
|
+
describe Synapse::Haproxy do
|
6
|
+
subject { Synapse::Haproxy.new(config['haproxy']) }
|
7
|
+
|
8
|
+
it 'updating the config' do
|
9
|
+
mockWatcher = mock(Synapse::ServiceWatcher)
|
10
|
+
binding.pry
|
11
|
+
subject.should_receive(:generate_config)
|
12
|
+
subject.update_config([mockWatcher])
|
13
|
+
end
|
14
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
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
|
7
|
+
require_relative '../lib/synapse'
|
8
|
+
require 'pry'
|
9
|
+
require_relative 'support/config'
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
13
|
+
config.run_all_when_everything_filtered = true
|
14
|
+
config.filter_run :focus
|
15
|
+
config.include Config
|
16
|
+
|
17
|
+
# Run specs in random order to surface order dependencies. If you find an
|
18
|
+
# order dependency and want to debug it, you can fix the order by providing
|
19
|
+
# the seed, which is printed after each run.
|
20
|
+
# --seed 1234
|
21
|
+
config.order = 'random'
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# list the services to connect
|
2
|
+
services:
|
3
|
+
- name: test
|
4
|
+
local_port: 3210
|
5
|
+
server_options: test_option
|
6
|
+
default_servers:
|
7
|
+
- { name: default1, host: localhost, port: 8080}
|
8
|
+
discovery:
|
9
|
+
method: zookeeper
|
10
|
+
path: /airbnb/service/logging/event_collector
|
11
|
+
hosts:
|
12
|
+
- localhost:2181
|
13
|
+
listen:
|
14
|
+
- test_option
|
15
|
+
|
16
|
+
|
17
|
+
# settings for haproxy including the global config
|
18
|
+
haproxy:
|
19
|
+
reload_command: "sudo service haproxy reload"
|
20
|
+
config_file_path: "/etc/haproxy/haproxy.cfg"
|
21
|
+
do_writes: false
|
22
|
+
do_reloads: false
|
23
|
+
global:
|
24
|
+
- global_test_option
|
25
|
+
|
26
|
+
defaults:
|
27
|
+
- default_test_option
|
data/synapse.gemspec
CHANGED
@@ -16,4 +16,11 @@ 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
|
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_runtime_dependency "zk", "~> 1.7.4"
|
21
|
+
gem.add_runtime_dependency "thrift", "~> 0.9.0"
|
22
|
+
|
23
|
+
gem.add_development_dependency "rspec"
|
24
|
+
gem.add_development_dependency "pry"
|
25
|
+
gem.add_development_dependency "pry-nav"
|
19
26
|
end
|
data/test.sh
ADDED
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.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,23 +9,137 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
12
|
+
date: 2013-10-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: zk
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.7.4
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.7.4
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: thrift
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.9.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.9.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: pry
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: pry-nav
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
14
94
|
description: ': Write a gem description'
|
15
95
|
email:
|
16
96
|
- martin.rhoads@airbnb.com
|
17
|
-
executables:
|
97
|
+
executables:
|
98
|
+
- synapse
|
18
99
|
extensions: []
|
19
100
|
extra_rdoc_files: []
|
20
101
|
files:
|
21
102
|
- .gitignore
|
103
|
+
- .rspec
|
22
104
|
- Gemfile
|
105
|
+
- Gemfile.lock
|
23
106
|
- LICENSE.txt
|
24
107
|
- README.md
|
25
108
|
- Rakefile
|
109
|
+
- Vagrantfile
|
110
|
+
- bin/synapse
|
111
|
+
- chef/converge
|
112
|
+
- chef/cookbooks/lxc/recipes/default.rb
|
113
|
+
- chef/cookbooks/synapse/attributes/default.rb
|
114
|
+
- chef/cookbooks/synapse/recipes/default.rb
|
115
|
+
- chef/run.json
|
116
|
+
- chef/run.rb
|
117
|
+
- client/.RData
|
118
|
+
- client/.Rhistory
|
119
|
+
- client/bench_rewrite_config.dat
|
120
|
+
- client/benchmark-client.iml
|
121
|
+
- client/pom.xml
|
122
|
+
- client/src/main/java/ClientArsch.java
|
123
|
+
- client/src/main/java/META-INF/MANIFEST.MF
|
124
|
+
- config/synapse.conf.json
|
125
|
+
- haproxy.pid
|
126
|
+
- lib/gen-rb/endpoint_types.rb
|
127
|
+
- lib/gen-rb/thrift.rb
|
26
128
|
- lib/synapse.rb
|
129
|
+
- lib/synapse/base.rb
|
130
|
+
- lib/synapse/haproxy.rb
|
131
|
+
- lib/synapse/service_watcher.rb
|
132
|
+
- lib/synapse/service_watcher/base.rb
|
133
|
+
- lib/synapse/service_watcher/dns.rb
|
134
|
+
- lib/synapse/service_watcher/ec2tag.rb
|
135
|
+
- lib/synapse/service_watcher/zookeeper.rb
|
27
136
|
- lib/synapse/version.rb
|
137
|
+
- spec/lib/synapse/haproxy_spec.rb
|
138
|
+
- spec/spec_helper.rb
|
139
|
+
- spec/support/config.rb
|
140
|
+
- spec/support/minimum.conf.yaml
|
28
141
|
- synapse.gemspec
|
142
|
+
- test.sh
|
29
143
|
homepage: ''
|
30
144
|
licenses: []
|
31
145
|
post_install_message:
|
@@ -50,4 +164,8 @@ rubygems_version: 1.8.23
|
|
50
164
|
signing_key:
|
51
165
|
specification_version: 3
|
52
166
|
summary: ': Write a gem summary'
|
53
|
-
test_files:
|
167
|
+
test_files:
|
168
|
+
- spec/lib/synapse/haproxy_spec.rb
|
169
|
+
- spec/spec_helper.rb
|
170
|
+
- spec/support/config.rb
|
171
|
+
- spec/support/minimum.conf.yaml
|