nerve 0.3.0 → 0.5.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.
- data/.travis.yml +5 -0
- data/CONTRIBUTING.md +14 -0
- data/Gemfile.lock +19 -7
- data/README.md +14 -6
- data/Rakefile +6 -0
- data/bin/nerve +18 -8
- data/example/nerve.conf.json +6 -3
- data/example/nerve_services/service1.json +2 -1
- data/lib/nerve/reporter/base.rb +26 -0
- data/lib/nerve/reporter/zookeeper.rb +70 -0
- data/lib/nerve/reporter.rb +8 -57
- data/lib/nerve/service_watcher.rb +2 -9
- data/lib/nerve/version.rb +1 -1
- data/lib/nerve.rb +5 -2
- data/nerve.gemspec +4 -1
- data/spec/.gitkeep +0 -0
- data/spec/lib/nerve/reporter_spec.rb +27 -0
- data/spec/lib/nerve/reporter_zookeeper_spec.rb +17 -0
- data/spec/spec_helper.rb +20 -0
- metadata +49 -5
data/.travis.yml
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Contributing Guidelines #
|
2
|
+
|
3
|
+
Thanks for contributing to SmartStack!
|
4
|
+
If you're opening a new PR, please ask for a merge into our `pull_requests` branch -- *not* `master`.
|
5
|
+
This will allow us avoid a back-and-forth by quickly accepting your PR and then making minor changes or doing testing before merging into `master`.
|
6
|
+
|
7
|
+
## Writing Checks ##
|
8
|
+
|
9
|
+
We welcome additional service checks into the core of nerve.
|
10
|
+
However, your checks must follow a few guidelines or they will not be accepted:
|
11
|
+
|
12
|
+
* be sure to respect timeouts; checks that do not time-out will not be accepted
|
13
|
+
* do NOT shell out; this becomes very expensive when done frequently
|
14
|
+
* use well-tested, stable, core libraries whenever possible
|
data/Gemfile.lock
CHANGED
@@ -1,23 +1,33 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nerve (0.
|
5
|
-
bunny (= 1.
|
4
|
+
nerve (0.5.0)
|
5
|
+
bunny (= 1.1.0)
|
6
6
|
zk (~> 1.9.2)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
amq-protocol (1.
|
12
|
-
bunny (1.
|
13
|
-
amq-protocol (>= 1.
|
11
|
+
amq-protocol (1.9.2)
|
12
|
+
bunny (1.1.0)
|
13
|
+
amq-protocol (>= 1.9.2)
|
14
|
+
diff-lcs (1.2.5)
|
14
15
|
little-plugger (1.1.3)
|
15
16
|
logging (1.7.2)
|
16
17
|
little-plugger (>= 1.1.3)
|
17
|
-
|
18
|
+
rake (10.1.1)
|
19
|
+
rspec (2.14.1)
|
20
|
+
rspec-core (~> 2.14.0)
|
21
|
+
rspec-expectations (~> 2.14.0)
|
22
|
+
rspec-mocks (~> 2.14.0)
|
23
|
+
rspec-core (2.14.7)
|
24
|
+
rspec-expectations (2.14.4)
|
25
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
26
|
+
rspec-mocks (2.14.4)
|
27
|
+
zk (1.9.3)
|
18
28
|
logging (~> 1.7.2)
|
19
29
|
zookeeper (~> 1.4.0)
|
20
|
-
zookeeper (1.4.
|
30
|
+
zookeeper (1.4.8)
|
21
31
|
|
22
32
|
PLATFORMS
|
23
33
|
java
|
@@ -25,3 +35,5 @@ PLATFORMS
|
|
25
35
|
|
26
36
|
DEPENDENCIES
|
27
37
|
nerve!
|
38
|
+
rake
|
39
|
+
rspec
|
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[](https://travis-ci.org/airbnb/nerve)
|
2
|
+
|
1
3
|
# Nerve
|
2
4
|
|
3
5
|
Nerve is a utility for tracking the status of machines and services.
|
@@ -8,7 +10,7 @@ The combination of Nerve and [Synapse](https://github.com/airbnb/synapse) make s
|
|
8
10
|
## Motivation ##
|
9
11
|
|
10
12
|
We already use [Synapse](https://github.com/airbnb/synapse) to discover remote services.
|
11
|
-
However, those services needed boilerplate code to register themselves in [Zookeeper](zookeeper.apache.org/).
|
13
|
+
However, those services needed boilerplate code to register themselves in [Zookeeper](http://zookeeper.apache.org/).
|
12
14
|
Nerve simplifies underlying services, enables code reuse, and allows us to create a more composable system.
|
13
15
|
It does so by factoring out the boilerplate into it's own application, which independenly handles monitoring and reporting.
|
14
16
|
|
@@ -36,7 +38,7 @@ It is usually called `nerve.conf.json`.
|
|
36
38
|
An example config file is available in `example/nerve.conf.json`.
|
37
39
|
The config file is composed of two main sections:
|
38
40
|
|
39
|
-
* `instance_id`: the name
|
41
|
+
* `instance_id`: the name nerve will submit when registering services; makes debugging easier
|
40
42
|
* `services`: the hash (from service name to config) of the services nerve will be monitoring
|
41
43
|
* `service_conf_dir`: path to a directory in which each json file will be interpreted as a service with the basename of the file minus the .json extension
|
42
44
|
|
@@ -46,13 +48,19 @@ Each service that nerve will be monitoring is specified in the `services` hash.
|
|
46
48
|
The key is the name of the service, and the value is a configuration hash telling nerve how to monitor the service.
|
47
49
|
The configuration contains the following options:
|
48
50
|
|
49
|
-
* `
|
50
|
-
* `
|
51
|
-
* `
|
52
|
-
* `zk_path`: the path (or [znode](https://zookeeper.apache.org/doc/r3.1.2/zookeeperProgrammers.html#sc_zkDataModel_znodes)) where the registration will be created; nerve will create the [ephemeral node](https://zookeeper.apache.org/doc/r3.1.2/zookeeperProgrammers.html#Ephemeral+Nodes) that is the registration as a child of this path
|
51
|
+
* `host`: the default host on which to make service checks; you should make this your *public* ip to ensure your service is publically accessible
|
52
|
+
* `port`: the default port for service checks; nerve will report the `host`:`port` combo via your chosen reporter
|
53
|
+
* `reporter_type`: the mechanism used to report up/down information; depending on the reporter you choose, additional parameters may be required. Defaults to `zookeeper`
|
53
54
|
* `check_interval`: the frequency with which service checks will be initiated; defaults to `500ms`
|
54
55
|
* `checks`: a list of checks that nerve will perform; if all of the pass, the service will be registered; otherwise, it will be un-registered
|
55
56
|
|
57
|
+
#### Zookeeper Reporter ####
|
58
|
+
|
59
|
+
If you set your `reporter_type` to `"zookeeper"` you should also set these parameters:
|
60
|
+
|
61
|
+
* `zk_hosts`: a list of the zookeeper hosts comprising the [ensemble](https://zookeeper.apache.org/doc/r3.1.2/zookeeperAdmin.html#sc_zkMulitServerSetup) that nerve will submit registration to
|
62
|
+
* `zk_path`: the path (or [znode](https://zookeeper.apache.org/doc/r3.1.2/zookeeperProgrammers.html#sc_zkDataModel_znodes)) where the registration will be created; nerve will create the [ephemeral node](https://zookeeper.apache.org/doc/r3.1.2/zookeeperProgrammers.html#Ephemeral+Nodes) that is the registration as a child of this path
|
63
|
+
|
56
64
|
### Checks ###
|
57
65
|
|
58
66
|
The core of nerve is a set of service checks.
|
data/Rakefile
CHANGED
data/bin/nerve
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'yaml'
|
4
4
|
require 'optparse'
|
5
5
|
|
6
6
|
require 'nerve'
|
@@ -20,7 +20,13 @@ EOB
|
|
20
20
|
options[:config] = key
|
21
21
|
end
|
22
22
|
|
23
|
-
|
23
|
+
options[:instance_id] = ENV['NERVE_INSTANCE_ID']
|
24
|
+
opts.on('-i instance_id','--instance_id instance_id', String,
|
25
|
+
'reported as `name` to ZK; overrides instance id from config file') do |key,value|
|
26
|
+
options[:instance_id] = key
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on('-h', '--help', 'Display this screen') do
|
24
30
|
puts opts
|
25
31
|
exit
|
26
32
|
end
|
@@ -34,15 +40,15 @@ optparse.parse!
|
|
34
40
|
def parseconfig(filename)
|
35
41
|
# parse synapse config file
|
36
42
|
begin
|
37
|
-
c =
|
43
|
+
c = YAML::parse(File.read(filename))
|
38
44
|
rescue Errno::ENOENT => e
|
39
45
|
raise ArgumentError, "config file does not exist:\n#{e.inspect}"
|
40
46
|
rescue Errno::EACCES => e
|
41
47
|
raise ArgumentError, "could not open config file:\n#{e.inspect}"
|
42
|
-
rescue
|
43
|
-
raise "config file #{filename} is not
|
48
|
+
rescue YAML::ParseError => e
|
49
|
+
raise "config file #{filename} is not yaml:\n#{e.inspect}"
|
44
50
|
end
|
45
|
-
return c
|
51
|
+
return c.to_ruby
|
46
52
|
end
|
47
53
|
|
48
54
|
config = parseconfig(options[:config])
|
@@ -53,8 +59,12 @@ if config.has_key?('service_conf_dir')
|
|
53
59
|
if ! Dir.exists?(cdir) then
|
54
60
|
raise "service conf dir does not exist:#{cdir}"
|
55
61
|
end
|
56
|
-
cfiles = Dir.glob(File.join(cdir, '*.json'))
|
57
|
-
cfiles.each { |x| config['services'][File.basename(x[/(.*)\.json$/, 1])] = parseconfig(x) }
|
62
|
+
cfiles = Dir.glob(File.join(cdir, '*.{yaml,json}'))
|
63
|
+
cfiles.each { |x| config['services'][File.basename(x[/(.*)\.(yaml|json)$/, 1])] = parseconfig(x) }
|
64
|
+
end
|
65
|
+
|
66
|
+
if options[:instance_id] && !options[:instance_id].empty?
|
67
|
+
config['instance_id'] = options[:instance_id]
|
58
68
|
end
|
59
69
|
|
60
70
|
# create nerve object
|
data/example/nerve.conf.json
CHANGED
@@ -3,8 +3,9 @@
|
|
3
3
|
"service_conf_dir": "example/nerve_services",
|
4
4
|
"services": {
|
5
5
|
"your_http_service": {
|
6
|
+
"host": "1.2.3.4",
|
6
7
|
"port": 3000,
|
7
|
-
"
|
8
|
+
"reporter_type": "zookeeper",
|
8
9
|
"zk_hosts": ["localhost:2181"],
|
9
10
|
"zk_path": "/nerve/services/your_http_service/services",
|
10
11
|
"check_interval": 2,
|
@@ -19,8 +20,9 @@
|
|
19
20
|
]
|
20
21
|
},
|
21
22
|
"your_tcp_service": {
|
23
|
+
"host": "1.2.3.4",
|
22
24
|
"port": 6379,
|
23
|
-
"
|
25
|
+
"reporter_type": "zookeeper",
|
24
26
|
"zk_hosts": ["localhost:2181"],
|
25
27
|
"zk_path": "/nerve/services/your_tcp_service/services",
|
26
28
|
"check_interval": 2,
|
@@ -34,8 +36,9 @@
|
|
34
36
|
]
|
35
37
|
},
|
36
38
|
"rabbitmq_service": {
|
39
|
+
"host": "1.2.3.4",
|
37
40
|
"port": 5672,
|
38
|
-
"
|
41
|
+
"reporter_type": "zookeeper",
|
39
42
|
"zk_hosts": ["localhost:2181"],
|
40
43
|
"zk_path": "/nerve/services/your_rabbitmq_service/services",
|
41
44
|
"check_interval": 2,
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
class Nerve::Reporter
|
3
|
+
class Base
|
4
|
+
include Nerve::Utils
|
5
|
+
include Nerve::Logging
|
6
|
+
|
7
|
+
def initialize(opts)
|
8
|
+
end
|
9
|
+
|
10
|
+
def start
|
11
|
+
end
|
12
|
+
|
13
|
+
def report_up
|
14
|
+
end
|
15
|
+
|
16
|
+
def report_down
|
17
|
+
end
|
18
|
+
|
19
|
+
def update_data(new_data='')
|
20
|
+
end
|
21
|
+
|
22
|
+
def ping?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'nerve/reporter/base'
|
2
|
+
require 'zk'
|
3
|
+
|
4
|
+
class Nerve::Reporter
|
5
|
+
class Zookeeper < Base
|
6
|
+
def initalize(service)
|
7
|
+
%w{zk_hosts zk_path instance_id host port}.each do |required|
|
8
|
+
raise ArgumentError, "missing required argument #{required} for new service watcher" unless service[required]
|
9
|
+
end
|
10
|
+
@path = service['zk_hosts'].shuffle.join(',') + opts['zk_path']
|
11
|
+
@data = parse_data({'host' => service['host'], 'port' => service['port'], 'name' => service['instance_id']})
|
12
|
+
|
13
|
+
@key = "/#{service['instance_id']}_"
|
14
|
+
@full_key = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def start()
|
18
|
+
log.info "nerve: waiting to connect to zookeeper at #{@path}"
|
19
|
+
@zk = ZK.new(@path)
|
20
|
+
|
21
|
+
log.info "nerve: successfully created zk connection to #{@path}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def report_up()
|
25
|
+
zk_save
|
26
|
+
end
|
27
|
+
|
28
|
+
def report_down
|
29
|
+
zk_delete
|
30
|
+
end
|
31
|
+
|
32
|
+
def update_data(new_data='')
|
33
|
+
@data = parse_data(new_data)
|
34
|
+
zk_save
|
35
|
+
end
|
36
|
+
|
37
|
+
def ping?
|
38
|
+
return @zk.ping?
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def zk_delete
|
44
|
+
if @full_key
|
45
|
+
@zk.delete(@full_key, :ignore => :no_node)
|
46
|
+
@full_key = nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def zk_create
|
51
|
+
@full_key = @zk.create(@key, :data => @data, :mode => :ephemeral_sequential)
|
52
|
+
end
|
53
|
+
|
54
|
+
def zk_save
|
55
|
+
return zk_create unless @full_key
|
56
|
+
|
57
|
+
begin
|
58
|
+
@zk.set(@full_key, @data)
|
59
|
+
rescue ZK::Exceptions::NoNode
|
60
|
+
zk_create
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def parse_data(data)
|
65
|
+
return data if data.class == String
|
66
|
+
return data.to_json
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
data/lib/nerve/reporter.rb
CHANGED
@@ -1,64 +1,15 @@
|
|
1
|
-
require 'zk'
|
2
1
|
|
3
2
|
module Nerve
|
4
3
|
class Reporter
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@path = opts['hosts'].shuffle.join(',') + opts['path']
|
14
|
-
@data = parse_data(opts['data'] || '')
|
15
|
-
@key = opts['key']
|
16
|
-
@key.insert(0,'/') unless @key[0] == '/'
|
17
|
-
end
|
18
|
-
|
19
|
-
def start()
|
20
|
-
log.info "nerve: waiting to connect to zookeeper at #{@path}"
|
21
|
-
@zk = ZK.new(@path)
|
22
|
-
|
23
|
-
log.info "nerve: successfully created zk connection to #{@path}"
|
24
|
-
end
|
25
|
-
|
26
|
-
def report_up()
|
27
|
-
zk_save
|
28
|
-
end
|
29
|
-
|
30
|
-
def report_down
|
31
|
-
zk_delete
|
32
|
-
end
|
33
|
-
|
34
|
-
def update_data(new_data='')
|
35
|
-
@data = parse_data(new_data)
|
36
|
-
zk_save
|
37
|
-
end
|
38
|
-
|
39
|
-
def ping?
|
40
|
-
return @zk.ping?
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def zk_delete
|
46
|
-
@zk.delete(@key, :ignore => :no_node)
|
47
|
-
end
|
48
|
-
|
49
|
-
def zk_save
|
50
|
-
log.debug "nerve: writing data #{@data.class} to zk at #{@key} with #{@data.inspect}"
|
51
|
-
begin
|
52
|
-
@zk.set(@key,@data)
|
53
|
-
rescue ZK::Exceptions::NoNode => e
|
54
|
-
@zk.create(@key,:data => @data, :mode => :ephemeral)
|
4
|
+
def self.new_from_service(service)
|
5
|
+
type = service['reporter_type'] || 'zookeeper'
|
6
|
+
reporter = begin
|
7
|
+
require "nerve/reporter/#{type.downcase}"
|
8
|
+
self.const_get(type.downcase.capitalize)
|
9
|
+
rescue Exception => e
|
10
|
+
raise ArgumentError, "specified a reporter_type of #{type}, which could not be found: #{e}"
|
55
11
|
end
|
12
|
+
reporter.new(service)
|
56
13
|
end
|
57
|
-
|
58
|
-
def parse_data(data)
|
59
|
-
return data if data.class == String
|
60
|
-
return data.to_json
|
61
|
-
end
|
62
|
-
|
63
14
|
end
|
64
15
|
end
|
@@ -11,19 +11,14 @@ module Nerve
|
|
11
11
|
log.debug "nerve: creating service watcher object"
|
12
12
|
|
13
13
|
# check that we have all of the required arguments
|
14
|
-
%w{name instance_id host port
|
14
|
+
%w{name instance_id host port}.each do |required|
|
15
15
|
raise ArgumentError, "missing required argument #{required} for new service watcher" unless service[required]
|
16
16
|
end
|
17
17
|
|
18
18
|
@name = service['name']
|
19
19
|
|
20
20
|
# configure the reporter, which we use for talking to zookeeper
|
21
|
-
@reporter = Reporter.
|
22
|
-
'hosts' => service['zk_hosts'],
|
23
|
-
'path' => service['zk_path'],
|
24
|
-
'key' => "#{service['instance_id']}_#{@name}",
|
25
|
-
'data' => {'host' => service['host'], 'port' => service['port']},
|
26
|
-
})
|
21
|
+
@reporter = Reporter.new_from_service(service)
|
27
22
|
|
28
23
|
# instantiate the checks for this service
|
29
24
|
@service_checks = []
|
@@ -52,9 +47,7 @@ module Nerve
|
|
52
47
|
def run()
|
53
48
|
log.info "nerve: starting service watch #{@name}"
|
54
49
|
|
55
|
-
# begin by reporting down
|
56
50
|
@reporter.start()
|
57
|
-
@reporter.report_down
|
58
51
|
was_up = false
|
59
52
|
|
60
53
|
until $EXIT
|
data/lib/nerve/version.rb
CHANGED
data/lib/nerve.rb
CHANGED
@@ -42,9 +42,12 @@ module Nerve
|
|
42
42
|
|
43
43
|
begin
|
44
44
|
sleep
|
45
|
-
rescue
|
46
|
-
log.
|
45
|
+
rescue StandardError => e
|
46
|
+
log.error 'nerve: encountered unexpected exception #{e.inspect} in main thread'
|
47
|
+
raise e
|
48
|
+
ensure
|
47
49
|
$EXIT = true
|
50
|
+
log.warn 'nerve: reaping all watchers'
|
48
51
|
@watchers.each do |name, watcher_thread|
|
49
52
|
reap_watcher(name)
|
50
53
|
end
|
data/nerve.gemspec
CHANGED
@@ -18,5 +18,8 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
20
|
gem.add_runtime_dependency "zk", "~> 1.9.2"
|
21
|
-
gem.add_runtime_dependency "bunny", "= 1.
|
21
|
+
gem.add_runtime_dependency "bunny", "= 1.1.0"
|
22
|
+
|
23
|
+
gem.add_development_dependency "rake"
|
24
|
+
gem.add_development_dependency "rspec"
|
22
25
|
end
|
data/spec/.gitkeep
ADDED
File without changes
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Nerve::Reporter do
|
4
|
+
let(:subject) { {
|
5
|
+
'zk_hosts' => ['zkhost1', 'zkhost2'],
|
6
|
+
'zk_path' => 'zk_path',
|
7
|
+
'instance_id' => 'instance_id',
|
8
|
+
'host' => 'host',
|
9
|
+
'port' => 'port'
|
10
|
+
}
|
11
|
+
}
|
12
|
+
it 'can new_from_service' do
|
13
|
+
expect(Nerve::Reporter::Zookeeper).to receive(:new).with(subject).and_return('kerplunk')
|
14
|
+
expect(Nerve::Reporter.new_from_service(subject)).to eq('kerplunk')
|
15
|
+
end
|
16
|
+
it 'actually constructs an instance of a specific backend' do
|
17
|
+
expect(Nerve::Reporter.new_from_service(subject).is_a?(Nerve::Reporter::Zookeeper)).to eql(true)
|
18
|
+
end
|
19
|
+
it 'the reporter backend inherits from the base class' do
|
20
|
+
expect(Nerve::Reporter.new_from_service(subject).is_a?(Nerve::Reporter::Base)).to eql(true)
|
21
|
+
end
|
22
|
+
it 'throws ArgumentError if you ask for a reporter type which does not exist' do
|
23
|
+
subject['reporter_type'] = 'does_not_exist'
|
24
|
+
expect { Nerve::Reporter.new_from_service(subject) }.to raise_error(ArgumentError)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'nerve/reporter/zookeeper'
|
3
|
+
|
4
|
+
describe Nerve::Reporter::Zookeeper do
|
5
|
+
let(:subject) { {
|
6
|
+
'zk_hosts' => ['zkhost1', 'zkhost2'],
|
7
|
+
'zk_path' => 'zk_path',
|
8
|
+
'instance_id' => 'instance_id',
|
9
|
+
'host' => 'host',
|
10
|
+
'port' => 'port'
|
11
|
+
}
|
12
|
+
}
|
13
|
+
it 'actually constructs an instance' do
|
14
|
+
expect(Nerve::Reporter::Zookeeper.new(subject).is_a?(Nerve::Reporter::Zookeeper)).to eql(true)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
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 "#{File.dirname(__FILE__)}/../lib/nerve"
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
11
|
+
config.run_all_when_everything_filtered = true
|
12
|
+
config.filter_run :focus
|
13
|
+
config.include Config
|
14
|
+
|
15
|
+
# Run specs in random order to surface order dependencies. If you find an
|
16
|
+
# order dependency and want to debug it, you can fix the order by providing
|
17
|
+
# the seed, which is printed after each run.
|
18
|
+
# --seed 1234
|
19
|
+
config.order = 'random'
|
20
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nerve
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2014-
|
14
|
+
date: 2014-03-03 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: zk
|
@@ -36,7 +36,7 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - '='
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: 1.
|
39
|
+
version: 1.1.0
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -44,7 +44,39 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 1.
|
47
|
+
version: 1.1.0
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rake
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: rspec
|
66
|
+
requirement: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
type: :development
|
73
|
+
prerelease: false
|
74
|
+
version_requirements: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
48
80
|
description: description
|
49
81
|
email:
|
50
82
|
- martin.rhoads@airbnb.com
|
@@ -57,6 +89,8 @@ files:
|
|
57
89
|
- .gitignore
|
58
90
|
- .mailmap
|
59
91
|
- .nerve.rc
|
92
|
+
- .travis.yml
|
93
|
+
- CONTRIBUTING.md
|
60
94
|
- Gemfile
|
61
95
|
- Gemfile.lock
|
62
96
|
- LICENSE.txt
|
@@ -69,6 +103,8 @@ files:
|
|
69
103
|
- lib/nerve.rb
|
70
104
|
- lib/nerve/log.rb
|
71
105
|
- lib/nerve/reporter.rb
|
106
|
+
- lib/nerve/reporter/base.rb
|
107
|
+
- lib/nerve/reporter/zookeeper.rb
|
72
108
|
- lib/nerve/ring_buffer.rb
|
73
109
|
- lib/nerve/service_watcher.rb
|
74
110
|
- lib/nerve/service_watcher/base.rb
|
@@ -78,6 +114,10 @@ files:
|
|
78
114
|
- lib/nerve/utils.rb
|
79
115
|
- lib/nerve/version.rb
|
80
116
|
- nerve.gemspec
|
117
|
+
- spec/.gitkeep
|
118
|
+
- spec/lib/nerve/reporter_spec.rb
|
119
|
+
- spec/lib/nerve/reporter_zookeeper_spec.rb
|
120
|
+
- spec/spec_helper.rb
|
81
121
|
homepage: ''
|
82
122
|
licenses: []
|
83
123
|
post_install_message:
|
@@ -102,4 +142,8 @@ rubygems_version: 1.8.23
|
|
102
142
|
signing_key:
|
103
143
|
specification_version: 3
|
104
144
|
summary: summary
|
105
|
-
test_files:
|
145
|
+
test_files:
|
146
|
+
- spec/.gitkeep
|
147
|
+
- spec/lib/nerve/reporter_spec.rb
|
148
|
+
- spec/lib/nerve/reporter_zookeeper_spec.rb
|
149
|
+
- spec/spec_helper.rb
|