boutons 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/bin/console +2 -10
- data/boutons.gemspec +4 -3
- data/lib/boutons/config.rb +19 -6
- data/lib/boutons/resource.rb +16 -0
- data/lib/boutons/uri.rb +70 -0
- data/lib/boutons/version.rb +1 -1
- data/lib/boutons.rb +83 -65
- metadata +23 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6335817799c818e80c5e9b9042192f6d259d5ee1
|
4
|
+
data.tar.gz: bd818a6d33cc0fc7bb23ad3bb2aabc3714884a0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a401dee9068d6fbc4f595a36e6e132a607200fda967961a9f10bab13b1edda3d6becaf1b88356e3720796067f33b155cee52bcd727e8670b45aa8a2dfaeea64
|
7
|
+
data.tar.gz: 352b06e6490ffe2e2ee83925dfb7988d6dd17cd3e41730311a6c91c6a8d8d30cd247d102fb021cc785abdec5f5d4e360da01bdb7d139d5f8d22485a937dcbf00
|
data/.gitignore
CHANGED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
boutons
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.2.2
|
data/bin/console
CHANGED
@@ -2,13 +2,5 @@
|
|
2
2
|
|
3
3
|
require "bundler/setup"
|
4
4
|
require "boutons"
|
5
|
-
|
6
|
-
|
7
|
-
# with your gem easier. You can also use a different console, if you like.
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require "pry"
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
14
|
-
IRB.start
|
5
|
+
require "pry"
|
6
|
+
Pry.start
|
data/boutons.gemspec
CHANGED
@@ -22,10 +22,11 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_dependency "synapse-easy", "~> 0.1"
|
23
23
|
spec.add_dependency "synapse-config", "~> 0.1"
|
24
24
|
spec.add_dependency "synapse-logging-interchangeable", "~> 0.1"
|
25
|
-
spec.add_dependency "toml-rb"
|
26
25
|
spec.add_dependency "recursive-open-struct"
|
27
|
-
spec.add_dependency "
|
26
|
+
spec.add_dependency "toml-rb"
|
27
|
+
spec.add_dependency "activesupport"
|
28
28
|
|
29
|
+
spec.add_development_dependency "bundler", "~> 1.8"
|
29
30
|
spec.add_development_dependency "rake", "~> 10.0"
|
30
|
-
spec.add_development_dependency "
|
31
|
+
spec.add_development_dependency "pry"
|
31
32
|
end
|
data/lib/boutons/config.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "toml"
|
2
2
|
require "recursive-open-struct"
|
3
|
+
require "active_support/core_ext/hash/deep_merge"
|
3
4
|
|
4
5
|
module Boutons
|
5
6
|
class Config < RecursiveOpenStruct
|
@@ -8,15 +9,27 @@ module Boutons
|
|
8
9
|
%w{. config/ ~/.boutons ~/ /etc/boutons /etc}.product(%w{tml toml}).collect{|x|File.expand_path x.join("/boutons.")}.each do |file|
|
9
10
|
return file if File.exists? file
|
10
11
|
end
|
12
|
+
nil
|
11
13
|
end
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end rescue nil
|
14
|
+
# privaste
|
15
|
+
def defaults
|
16
|
+
{ :registry => { :zookeeper => { :hosts => [ "localhost:2181" ] } } }
|
16
17
|
end
|
17
|
-
|
18
|
+
def with_environment
|
19
|
+
environment = defaults
|
20
|
+
environment[:registry][:zookeeper][:hosts] = ENV["ZK_HOSTS"].split(",") if ENV["ZK_HOSTS"]
|
21
|
+
environment
|
22
|
+
end
|
23
|
+
def with_configuration
|
24
|
+
file ? TOML.load_file(file,symbolize_keys:true) : {}
|
25
|
+
end
|
18
26
|
def config params={}
|
19
|
-
@config
|
27
|
+
unless @config
|
28
|
+
params.deep_merge! with_environment
|
29
|
+
params.deep_merge! with_configuration
|
30
|
+
@config = self.new params
|
31
|
+
end
|
32
|
+
@config
|
20
33
|
end
|
21
34
|
def method_missing method, *args, &block
|
22
35
|
config.send(method, *args, &block) rescue nil
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Boutons
|
2
|
+
class Resource
|
3
|
+
class << self
|
4
|
+
def add name, object
|
5
|
+
self.instance_variable_set("@#{name}",object)
|
6
|
+
end
|
7
|
+
private
|
8
|
+
def method_missing method, *args, &block
|
9
|
+
if self.instance_variable_defined?("@#{method.to_s}")
|
10
|
+
return self.instance_variable_get("@#{method.to_s}")
|
11
|
+
end
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/boutons/uri.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require "uri"
|
2
|
+
require "boutons/resource"
|
3
|
+
|
4
|
+
module Boutons
|
5
|
+
class URI
|
6
|
+
class Registry
|
7
|
+
def initialize uri
|
8
|
+
@uri = uri
|
9
|
+
end
|
10
|
+
def service
|
11
|
+
@uri.scheme
|
12
|
+
end
|
13
|
+
def zk_hosts
|
14
|
+
Boutons::Config.registry.send(service).hosts
|
15
|
+
end
|
16
|
+
def zk
|
17
|
+
begin
|
18
|
+
# return existing, working zookeeper connection
|
19
|
+
Boutons::Resource.zk
|
20
|
+
rescue
|
21
|
+
queue = Queue.new
|
22
|
+
threads = []
|
23
|
+
zk_hosts.each do |zk_host|
|
24
|
+
threads << Thread.new do
|
25
|
+
# connect, push connection to queue
|
26
|
+
queue << [zk_host,ZK.new(zk_host)]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
host,zk = queue.pop
|
30
|
+
# set first working host as host arrays
|
31
|
+
Boutons::Config.registry.zookeeper.hosts = [host]
|
32
|
+
# register connection
|
33
|
+
Boutons::Resource.add :zk, zk
|
34
|
+
# Add later connections if there are any
|
35
|
+
Thread.new do
|
36
|
+
threads.each{|t|t.join}
|
37
|
+
host,zk = queue.pop
|
38
|
+
Boutons::Config.registry.zookeeper.hosts << host if zk.ping?
|
39
|
+
end
|
40
|
+
retry
|
41
|
+
end
|
42
|
+
end
|
43
|
+
def zk_path
|
44
|
+
return @zk_path if @zk_path
|
45
|
+
paths = []
|
46
|
+
paths << "nerve"
|
47
|
+
paths += @uri.path.split("/")[1..-1].join("/#{@uri.host}/").split("/")
|
48
|
+
paths << "services"
|
49
|
+
paths.inject([Pathname.new("/")]) do |paths,dir|
|
50
|
+
paths << paths.last.join(dir)
|
51
|
+
end.map{|p|p.to_s}.reverse.each do |path|
|
52
|
+
return @zk_path = path unless zk.children(path).empty?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
def initialize uri
|
57
|
+
@uri ||= URI uri
|
58
|
+
end
|
59
|
+
def registry
|
60
|
+
@registry ||= Registry.new @uri
|
61
|
+
end
|
62
|
+
def type
|
63
|
+
@uri.scheme
|
64
|
+
end
|
65
|
+
private
|
66
|
+
def method_missing method, *args, &block
|
67
|
+
@uri.send method, *args, &block
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/boutons/version.rb
CHANGED
data/lib/boutons.rb
CHANGED
@@ -4,130 +4,148 @@ require "synapse"
|
|
4
4
|
require "synapse/easy"
|
5
5
|
require "synapse/config"
|
6
6
|
require "active_support/core_ext/hash/indifferent_access"
|
7
|
+
require "active_support/core_ext/string/inflections"
|
7
8
|
require "zookeeper"
|
8
9
|
require "boutons/synapse"
|
9
10
|
require "synapse/logging/interchangeable"
|
11
|
+
require "boutons/uri"
|
12
|
+
require "boutons/resource"
|
10
13
|
|
11
14
|
module Boutons
|
12
|
-
class
|
15
|
+
class UnknownSynapse < Exception; end
|
16
|
+
class MissingSynapse < Exception; end
|
13
17
|
class << self
|
14
|
-
@@haproxy = Synapse::Config::Haproxy.new Synapse::Easy::Haproxy.new
|
15
|
-
@@services = Synapse::Config::Services.new
|
16
|
-
@@config = { services: @@services, haproxy: @@haproxy }.with_indifferent_access
|
17
|
-
@@logger = Logger.new(STDERR,progname:"Boutons")
|
18
|
-
@@mapping = {}
|
19
18
|
def add synapse
|
20
|
-
return if
|
21
|
-
|
22
|
-
|
19
|
+
return if services[synapse.name]
|
20
|
+
services[synapse.name] = synapse
|
21
|
+
start
|
23
22
|
update
|
24
23
|
end
|
25
24
|
def remove name
|
26
|
-
|
27
|
-
|
25
|
+
services[mapping[name]] = nil
|
26
|
+
start
|
28
27
|
update
|
29
28
|
end
|
30
29
|
def with_loggers
|
31
|
-
|
30
|
+
synapse.service_watchers.collect{|s|s.logger}+[logger,synapse.logger].each do |logger|
|
32
31
|
yield(logger) if block_given?
|
33
32
|
end
|
34
33
|
end
|
35
34
|
def log_with logger, synapses:nil
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
logger.info "Replace logger #{logger} with #{logger}"
|
36
|
+
logger=logger
|
37
|
+
synapse.logger=logger
|
39
38
|
return unless synapses
|
40
39
|
if synapses.to_sym == :all
|
41
|
-
return
|
40
|
+
return synapse.service_watchers.map{|s|s.logger=logger}
|
42
41
|
end
|
43
|
-
|
42
|
+
synapse.service_watchers.each do |services_watcher|
|
44
43
|
if synapses==services_watcher.name
|
45
|
-
services_watcher.logger =
|
44
|
+
services_watcher.logger = logger
|
46
45
|
end
|
47
46
|
end
|
48
47
|
end
|
49
48
|
def haproxy
|
50
|
-
@@haproxy
|
49
|
+
@@haproxy ||= Synapse::Config::Haproxy.new Synapse::Easy::Haproxy.new
|
51
50
|
end
|
52
51
|
def all
|
53
|
-
|
52
|
+
services
|
54
53
|
end
|
55
54
|
private
|
56
|
-
def
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
@@services
|
61
|
-
|
55
|
+
def mapping
|
56
|
+
@@mapping ||= {}
|
57
|
+
end
|
58
|
+
def config
|
59
|
+
@@config ||= { services: services, haproxy: haproxy }.with_indifferent_access
|
60
|
+
end
|
61
|
+
def services
|
62
|
+
@@services ||= Synapse::Config::Services.new
|
63
|
+
end
|
64
|
+
def logger
|
65
|
+
@@logger ||= Logger.new(STDERR,progname:"Boutons")
|
66
|
+
end
|
67
|
+
def synapse
|
68
|
+
@@synapse ||= Synapse::Synapse.new config rescue nil
|
69
|
+
end
|
70
|
+
def start
|
71
|
+
return if @started
|
72
|
+
services.map{|n,s|s.active=true}
|
73
|
+
haproxy.inform synapse
|
62
74
|
at_exit do
|
63
|
-
|
64
|
-
pf =
|
65
|
-
cf =
|
66
|
-
sf =
|
75
|
+
logger.info "HAproxy cleanup begin"
|
76
|
+
pf = haproxy.pid_file_path
|
77
|
+
cf = haproxy.config_file_path
|
78
|
+
sf = haproxy.socket_file_path
|
67
79
|
pids = File.read(pf).strip
|
68
|
-
|
80
|
+
logger.info "HAproxy stop: `kill -9 #{pids}`"
|
69
81
|
`kill -9 #{pids}`
|
70
82
|
File.unlink(pf)
|
71
83
|
File.unlink(sf)
|
72
84
|
File.unlink(cf)
|
73
|
-
|
85
|
+
logger.info "HAproxy cleanup finish"
|
74
86
|
end
|
75
|
-
|
76
|
-
|
87
|
+
services.inform synapse
|
88
|
+
synapse.services = services
|
77
89
|
@@synapse_thread = Thread.new do
|
78
|
-
|
90
|
+
synapse.run
|
79
91
|
end
|
80
92
|
wait
|
93
|
+
@started = true
|
81
94
|
end
|
82
95
|
def wait
|
83
96
|
loop do
|
84
97
|
break unless restart_required
|
85
|
-
sleep 0.
|
98
|
+
sleep 0.25
|
86
99
|
end
|
87
100
|
end
|
88
101
|
def restart_required
|
89
|
-
|
102
|
+
synapse.instance_variable_get("@haproxy").instance_variable_get("@restart_required")
|
90
103
|
end
|
91
104
|
def update
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
@@mapping[normalize synapse.name] = name
|
105
|
+
services.each do |name,synapse|
|
106
|
+
next if mapping[normalize synapse.name]
|
107
|
+
mapping[normalize synapse.name] = name
|
96
108
|
end
|
97
|
-
|
109
|
+
services.each do |name,synapse|
|
98
110
|
synapse.aliases.each do |synapse_alias|
|
99
|
-
next if
|
100
|
-
|
111
|
+
next if mapping[normalize synapse_alias]
|
112
|
+
mapping[normalize synapse_alias] = name
|
101
113
|
end
|
102
114
|
end
|
103
115
|
end
|
104
116
|
def normalize name
|
105
117
|
name.to_s.gsub(/\./,"_").to_sym
|
106
118
|
end
|
107
|
-
def
|
108
|
-
return if
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
unless name
|
119
|
-
return @@services.send(method, *args, &block) if @@services.respond_to? method
|
120
|
-
raise SynapseNotFound.new("The Synapse #{method} is unavailable. Add service #{method} first.") unless name
|
119
|
+
def connect service
|
120
|
+
return if mapping[service]
|
121
|
+
Boutons::Config.services.send(service).each do |service_uri|
|
122
|
+
uri = Boutons::URI.new service_uri
|
123
|
+
params = {}
|
124
|
+
params[:application] = uri.host
|
125
|
+
params[:method] = uri.registry.service
|
126
|
+
params[:path] = uri.registry.zk_path
|
127
|
+
params[:hosts] = uri.registry.zk_hosts
|
128
|
+
params[:name] = uri.registry.zk_path[1..-1].gsub(/\//,"_")
|
129
|
+
add Synapse::Easy::Service.new params
|
121
130
|
end
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
131
|
+
end
|
132
|
+
def connectable? service
|
133
|
+
Boutons::Config.services.keys.include? service
|
134
|
+
end
|
135
|
+
def connection service
|
136
|
+
services[mapping[service]]
|
137
|
+
end
|
138
|
+
def setup service, *args, &block
|
139
|
+
raise UnknownSynapse.new("Synapse #{service} is unknown") unless connectable? service
|
140
|
+
connect service
|
141
|
+
end
|
142
|
+
def resolv service
|
143
|
+
raise MissingSynapse.new("Synapse #{service} is missing") unless connection service
|
144
|
+
connection service
|
128
145
|
end
|
129
146
|
def method_missing method, *args, &block
|
130
|
-
|
147
|
+
setup method, *args, &block
|
148
|
+
resolv method
|
131
149
|
end
|
132
150
|
end
|
133
151
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: boutons
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mathias Kaufmann
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: synapse
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: recursive-open-struct
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: toml-rb
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,7 +95,7 @@ dependencies:
|
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
98
|
+
name: activesupport
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
101
|
- - ">="
|
@@ -101,7 +115,7 @@ dependencies:
|
|
101
115
|
- - "~>"
|
102
116
|
- !ruby/object:Gem::Version
|
103
117
|
version: '1.8'
|
104
|
-
type: :
|
118
|
+
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
@@ -123,7 +137,7 @@ dependencies:
|
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '10.0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
140
|
+
name: pry
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
128
142
|
requirements:
|
129
143
|
- - ">="
|
@@ -145,6 +159,8 @@ extensions: []
|
|
145
159
|
extra_rdoc_files: []
|
146
160
|
files:
|
147
161
|
- ".gitignore"
|
162
|
+
- ".ruby-gemset"
|
163
|
+
- ".ruby-version"
|
148
164
|
- ".travis.yml"
|
149
165
|
- Gemfile
|
150
166
|
- README.md
|
@@ -154,7 +170,9 @@ files:
|
|
154
170
|
- boutons.gemspec
|
155
171
|
- lib/boutons.rb
|
156
172
|
- lib/boutons/config.rb
|
173
|
+
- lib/boutons/resource.rb
|
157
174
|
- lib/boutons/synapse.rb
|
175
|
+
- lib/boutons/uri.rb
|
158
176
|
- lib/boutons/version.rb
|
159
177
|
homepage: https://synapse.stei.gr/boutons
|
160
178
|
licenses: []
|