boutons 0.2.1 → 0.3.0
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.
- 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: []
|