vidocq 0.0.7
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 +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +35 -0
- data/Rakefile +2 -0
- data/lib/vidocq.rb +55 -0
- data/lib/vidocq/cache.rb +37 -0
- data/lib/vidocq/connection.rb +52 -0
- data/lib/vidocq/railtie.rb +9 -0
- data/lib/vidocq/version.rb +3 -0
- data/vidocq.gemspec +19 -0
- metadata +79 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Companybook AS
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# Vidocq
|
2
|
+
|
3
|
+
As you know, a gem isn't cool without an obscure name. Which is why Vidocq gets its name from the first known private investigator, [Eugène
|
4
|
+
François Vidocq](http://en.wikipedia.org/wiki/Eug%C3%A8ne_Fran%C3%A7ois_Vidocq).
|
5
|
+
Vidocq is a library for hunting down service instances. Services that
|
6
|
+
register as running using an ephemeral zookeeper znode can be discovered
|
7
|
+
with Vidocq.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
```ruby
|
13
|
+
gem 'vidocq'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
$ gem install vidocq
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
```ruby
|
25
|
+
v = Vidocq.new('my-service', '0.1', :zk => 'myzkserver:2181', :ttl => 10)
|
26
|
+
response = v.call(:id => '42')
|
27
|
+
```
|
28
|
+
|
29
|
+
## Contributing
|
30
|
+
|
31
|
+
1. Fork it
|
32
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
33
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
34
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
35
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/vidocq.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'zk'
|
2
|
+
require 'json'
|
3
|
+
require 'vidocq/connection'
|
4
|
+
require 'vidocq/railtie' if defined? ::Rails::Railtie
|
5
|
+
|
6
|
+
module Vidocq
|
7
|
+
|
8
|
+
class NoEndpointError < StandardError; end
|
9
|
+
class NoResponseError < StandardError; end
|
10
|
+
|
11
|
+
# Connection factory
|
12
|
+
def self.new(sid, version, opts = {})
|
13
|
+
Connection.new(sid, version, opts || {})
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.logger=(new_logger)
|
17
|
+
@logger = new_logger
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.logger
|
21
|
+
@logger ||= Logger.new(STDOUT)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Lists all the services, versions and instances
|
25
|
+
# in an hierarcical format like the following:
|
26
|
+
#
|
27
|
+
# [
|
28
|
+
# {:name => 'fooservice', :versions =>
|
29
|
+
# [
|
30
|
+
# {:number => '0.1', :instances =>
|
31
|
+
# [
|
32
|
+
# {:endpoint => 'http://198.0.0.1:8900/foo'}, ...
|
33
|
+
# ]
|
34
|
+
# }, ...
|
35
|
+
# ]
|
36
|
+
# }, ...
|
37
|
+
# ]
|
38
|
+
def self.services(connect_string = nikjl)
|
39
|
+
base_path = "/companybook/services"
|
40
|
+
ZK.open(connect_string || 'localhost:2181') do |zk|
|
41
|
+
return [] unless zk.exists?(base_path)
|
42
|
+
return zk.children(base_path).collect do |service|
|
43
|
+
service_path = base_path + '/' + service
|
44
|
+
versions = zk.children(service_path).collect do |version|
|
45
|
+
version_path = service_path + '/' + version
|
46
|
+
instances = zk.children(version_path).collect do |instance|
|
47
|
+
JSON.parse(zk.get(version_path + '/' + instance).first)
|
48
|
+
end
|
49
|
+
{:number => version, :instances => instances}
|
50
|
+
end
|
51
|
+
{:name => service, :versions => versions}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/vidocq/cache.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'zk'
|
3
|
+
|
4
|
+
module Vidocq
|
5
|
+
class Cache
|
6
|
+
def initialize(sid, version, opts = {})
|
7
|
+
@ttl = opts.fetch(:ttl, 0)
|
8
|
+
@cs = opts.fetch(:zk, 'localhost:2181')
|
9
|
+
@parent = "/companybook/services/#{sid}/#{version}"
|
10
|
+
@endpoints = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def endpoints
|
14
|
+
outdated? ? expire! : @endpoints
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def get_children(zk, path)
|
20
|
+
zk.children(path) rescue []
|
21
|
+
end
|
22
|
+
|
23
|
+
def outdated?
|
24
|
+
@endpoints.empty? or Time.now > (@last_request + @ttl)
|
25
|
+
end
|
26
|
+
|
27
|
+
def expire!
|
28
|
+
@last_request = Time.now
|
29
|
+
|
30
|
+
ZK.open(@cs) do |zk|
|
31
|
+
@endpoints = zk.children(@parent).collect do |child|
|
32
|
+
JSON.parse(zk.get(@parent + '/' + child).first)['endpoint']
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'cgi'
|
3
|
+
require 'vidocq/cache'
|
4
|
+
|
5
|
+
module Vidocq
|
6
|
+
class Connection
|
7
|
+
def initialize(sid, version, opts = {})
|
8
|
+
@fallbacks = opts.delete(:fallbacks) || []
|
9
|
+
@cache = Cache.new(sid, version, opts)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Finds an endpoint and calls it with the given options.
|
13
|
+
# If there is a connection failure, new attempts are
|
14
|
+
# made with new endpoints.
|
15
|
+
#
|
16
|
+
# Two failure modes are handled:
|
17
|
+
# 1. There are no registered endpoints: NoEndpointError
|
18
|
+
# 2. None of the registered endpoints respond: NoResponseError
|
19
|
+
def call(opts = {})
|
20
|
+
resource_id = opts.delete(:id)
|
21
|
+
endpoints = get_endpoints
|
22
|
+
raise NoEndpointError if endpoints.empty?
|
23
|
+
Vidocq.logger.info "Vidocq endpoints: #{endpoints}"
|
24
|
+
|
25
|
+
begin
|
26
|
+
endpoint = endpoints.slice!(rand(endpoints.size))
|
27
|
+
path = [endpoint, resource_id].compact.join('/')
|
28
|
+
url = "#{path}?#{build_querystring(opts)}"
|
29
|
+
begin
|
30
|
+
return HTTParty.get(url)
|
31
|
+
rescue Exception => e
|
32
|
+
Vidocq.logger.warn "Error requesting '#{url}': #{e}."
|
33
|
+
end
|
34
|
+
end while endpoints.any?
|
35
|
+
|
36
|
+
Vidocq.logger.warn "Vidocq: Unable to reach any of the endpoints"
|
37
|
+
|
38
|
+
raise NoResponseError
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_endpoints
|
42
|
+
endpoints = @cache.endpoints || []
|
43
|
+
endpoints.empty? ? @fallbacks : endpoints
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def build_querystring(opts = {})
|
49
|
+
opts.collect { |k,v| "#{k}=#{CGI::escape(v.to_s)}" }.join('&')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/vidocq.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.expand_path('../lib/vidocq/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.authors = ["Alexander Mossin"]
|
5
|
+
gem.email = ["alexander@companybook.no"]
|
6
|
+
gem.description = %q{A library for discover service instances registered in ZooKeeper.}
|
7
|
+
gem.summary = %q{A library for discover service instances registered in ZooKeeper.}
|
8
|
+
gem.homepage = ""
|
9
|
+
|
10
|
+
gem.files = `git ls-files`.split($\)
|
11
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
12
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
13
|
+
gem.name = "vidocq"
|
14
|
+
gem.require_paths = ["lib"]
|
15
|
+
gem.version = Vidocq::VERSION
|
16
|
+
|
17
|
+
gem.add_dependency('zk', '>= 1.6.4')
|
18
|
+
gem.add_dependency('httparty', '>= 0.8.0')
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vidocq
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.7
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alexander Mossin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-25 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: zk
|
16
|
+
requirement: &70342550833760 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.6.4
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70342550833760
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: httparty
|
27
|
+
requirement: &70342550833260 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.8.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70342550833260
|
36
|
+
description: A library for discover service instances registered in ZooKeeper.
|
37
|
+
email:
|
38
|
+
- alexander@companybook.no
|
39
|
+
executables: []
|
40
|
+
extensions: []
|
41
|
+
extra_rdoc_files: []
|
42
|
+
files:
|
43
|
+
- .gitignore
|
44
|
+
- Gemfile
|
45
|
+
- LICENSE
|
46
|
+
- README.md
|
47
|
+
- Rakefile
|
48
|
+
- lib/vidocq.rb
|
49
|
+
- lib/vidocq/cache.rb
|
50
|
+
- lib/vidocq/connection.rb
|
51
|
+
- lib/vidocq/railtie.rb
|
52
|
+
- lib/vidocq/version.rb
|
53
|
+
- vidocq.gemspec
|
54
|
+
homepage: ''
|
55
|
+
licenses: []
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 1.8.10
|
75
|
+
signing_key:
|
76
|
+
specification_version: 3
|
77
|
+
summary: A library for discover service instances registered in ZooKeeper.
|
78
|
+
test_files: []
|
79
|
+
has_rdoc:
|