cellect-client 0.1.3 → 1.0.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/.travis.yml +2 -8
- data/cellect-client.gemspec +1 -0
- data/cellect.gemspec +4 -3
- data/lib/cellect/client/connection.rb +12 -12
- data/lib/cellect/client/node_set.rb +5 -5
- data/lib/cellect/client/railtie.rb +8 -8
- data/lib/cellect/client.rb +6 -6
- data/lib/cellect/node_set.rb +12 -12
- data/lib/cellect/version.rb +1 -1
- data/lib/cellect.rb +1 -1
- data/spec/client/connection_spec.rb +17 -17
- data/spec/client/node_set_spec.rb +4 -2
- data/spec/spec_helper.rb +3 -4
- data/spec/support/shared_api_context.rb +2 -2
- data/spec/support/shared_examples_for_node_set.rb +3 -3
- data/spec/support/shared_examples_for_set.rb +6 -6
- data/spec/support/shared_examples_for_workflow.rb +5 -5
- data/spec/support/spec_adapter.rb +6 -6
- data/spec/support/zk_setup.rb +48 -25
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afa825f4a300482bd14b901c3329bb4cdbbdefc5
|
4
|
+
data.tar.gz: b05da041f863b7236b51d7589a13f105b8c0b7cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c91dc81813eb58e9801a8d05859e06134cc62b845deaa911d75cf9817ccdd083468cadc9af959e0bd4f5ae748ba463535103d3b82c0dded2e8a9d51c2250543
|
7
|
+
data.tar.gz: 61131fff07cc2d147b83ad68edea75dcc1238f3be3ca8baaf1c5895f7bb1cd10ae6eaaf5cac585c53ff3febc6e50ec0c19d016843deb8c335451660fb063e4bc
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -5,16 +5,10 @@ before_install:
|
|
5
5
|
- sudo add-apt-repository ppa:boost-latest/ppa -y
|
6
6
|
- sudo apt-get update -q
|
7
7
|
- sudo apt-get install -y autoconf automake boost1.55 libffi-dev
|
8
|
-
|
9
|
-
before_script:
|
10
|
-
- test `which zkServer.sh` && zkServer.sh stop && rm -rf /tmp/zookeeper/*; true
|
11
|
-
- wget -q -O - "http://mirrors.koehn.com/apache/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz" | tar zx -C "$HOME/"
|
12
|
-
- export PATH="$PATH:/$HOME/zookeeper-3.4.6/bin"
|
13
|
-
- cp "$HOME/zookeeper-3.4.6/conf/zoo_sample.cfg" "$HOME/zookeeper-3.4.6/conf/zoo.cfg"
|
14
|
-
- zkServer.sh start
|
8
|
+
- gem update bundler
|
15
9
|
|
16
10
|
rvm:
|
17
11
|
- 2.1.5
|
18
12
|
- 2.2.1
|
19
13
|
|
20
|
-
script:
|
14
|
+
script: bundle exec rake spec
|
data/cellect-client.gemspec
CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency 'rake'
|
26
26
|
spec.add_development_dependency 'oj'
|
27
27
|
spec.add_development_dependency 'rspec'
|
28
|
+
spec.add_development_dependency 'zk-server'
|
28
29
|
spec.add_development_dependency 'rack-test'
|
29
30
|
spec.add_development_dependency 'pry'
|
30
31
|
|
data/cellect.gemspec
CHANGED
@@ -12,23 +12,24 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.description = ''
|
13
13
|
spec.homepage = 'https://github.com/parrish/Cellect'
|
14
14
|
spec.license = 'MIT'
|
15
|
-
|
15
|
+
|
16
16
|
spec.files = ['lib/cellect.rb', 'lib/cellect/version.rb']
|
17
17
|
spec.executables = []
|
18
18
|
spec.test_files = []
|
19
19
|
spec.require_paths = ['lib']
|
20
|
-
|
20
|
+
|
21
21
|
spec.add_development_dependency 'bundler', '~> 1.5'
|
22
22
|
spec.add_development_dependency 'rake'
|
23
23
|
spec.add_development_dependency 'oj'
|
24
24
|
spec.add_development_dependency 'rspec'
|
25
25
|
spec.add_development_dependency 'rack-test'
|
26
|
+
spec.add_development_dependency 'zk-server'
|
26
27
|
spec.add_development_dependency 'pry'
|
27
28
|
spec.add_development_dependency 'puma', '~> 2.8'
|
28
29
|
spec.add_development_dependency 'pg', '~> 0.17'
|
29
30
|
spec.add_development_dependency 'connection_pool', '~> 2.0'
|
30
31
|
spec.add_development_dependency 'codeclimate-test-reporter'
|
31
|
-
|
32
|
+
|
32
33
|
spec.add_runtime_dependency 'cellect-server', Cellect::VERSION
|
33
34
|
spec.add_runtime_dependency 'cellect-client', Cellect::VERSION
|
34
35
|
end
|
@@ -7,53 +7,53 @@ module Cellect
|
|
7
7
|
class Connection
|
8
8
|
include Celluloid
|
9
9
|
include Celluloid::IO
|
10
|
-
|
10
|
+
|
11
11
|
# Reload the data for a workflow on all servers
|
12
12
|
def reload_workflow(id)
|
13
13
|
broadcast :post, "/workflows/#{ id }/reload"
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
# Remove the workflow from all servers
|
17
17
|
def delete_workflow(id)
|
18
18
|
broadcast :delete, "/workflows/#{ id }"
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
# Adds or updates a subject on all servers
|
22
22
|
def add_subject(id, workflow_id:, group_id: nil, priority: nil)
|
23
23
|
broadcast :put, "/workflows/#{ workflow_id }/add", querystring(subject_id: id, group_id: group_id, priority: priority)
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
# Removes a subject on all servers
|
27
27
|
def remove_subject(id, workflow_id:, group_id: nil)
|
28
28
|
broadcast :put, "/workflows/#{ workflow_id }/remove", querystring(subject_id: id, group_id: group_id)
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
# Preload a user on a server
|
32
32
|
def load_user(user_id:, host:, workflow_id:)
|
33
33
|
send_http host, :post, "/workflows/#{ workflow_id }/users/#{ user_id }/load"
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
# Adds a subject to a users seen set
|
37
37
|
def add_seen(subject_id:, user_id:, host:, workflow_id:)
|
38
38
|
send_http host, :put, "/workflows/#{ workflow_id }/users/#{ user_id }/add_seen", querystring(subject_id: subject_id)
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
# Gets unseen subjects for a user
|
42
42
|
def get_subjects(user_id:, host:, workflow_id:, limit: nil, group_id: nil)
|
43
43
|
response = send_http host, :get, "/workflows/#{ workflow_id }", querystring(user_id: user_id, group_id: group_id, limit: limit)
|
44
44
|
ensure_valid_response response
|
45
45
|
MultiJson.load response.body
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
protected
|
49
|
-
|
49
|
+
|
50
50
|
# Broadcast by iterating over each server
|
51
51
|
def broadcast(action, path, query = '')
|
52
52
|
Cellect::Client.node_set.nodes.each_pair do |node, host|
|
53
53
|
send_http host, action, path, query
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
# Makes an API call through an evented Celluloid Socket
|
58
58
|
def send_http(host, action, path, query = '')
|
59
59
|
params = { host: host, path: path }
|
@@ -61,7 +61,7 @@ module Cellect
|
|
61
61
|
uri = URI::HTTP.build params
|
62
62
|
HTTP.send action, uri.to_s, socket_class: Celluloid::IO::TCPSocket
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
# Builds a querystring from a hash
|
66
66
|
def querystring(hash = { })
|
67
67
|
[].tap do |list|
|
@@ -71,7 +71,7 @@ module Cellect
|
|
71
71
|
end
|
72
72
|
end.join('&')
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
# Ensure the API response was OK
|
76
76
|
def ensure_valid_response(response)
|
77
77
|
unless response.code == 200
|
@@ -4,15 +4,15 @@ module Cellect
|
|
4
4
|
module Client
|
5
5
|
class NodeSet < Cellect::NodeSet
|
6
6
|
attr_accessor :nodes
|
7
|
-
|
7
|
+
|
8
8
|
# Sets up an empty node set
|
9
9
|
def initialize(zk_url = nil)
|
10
10
|
self.nodes = { }
|
11
11
|
super
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
protected
|
15
|
-
|
15
|
+
|
16
16
|
# Respond to a node coming online or timing out
|
17
17
|
def nodes_changed(nodes)
|
18
18
|
self.nodes = { }
|
@@ -20,14 +20,14 @@ module Cellect
|
|
20
20
|
self.nodes[node] = zk.get("/nodes/#{ node }").first
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
# Register with ZooKeeper and get the list of nodes
|
25
25
|
def setup
|
26
26
|
watch_nodes
|
27
27
|
zk.mkdir_p '/nodes'
|
28
28
|
nodes_changed zk.children('/nodes', watch: true)
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
# Watch ZooKeeper for changes to the node set
|
32
32
|
def watch_nodes
|
33
33
|
zk.register('/nodes') do |event|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Cellect
|
2
2
|
module Client
|
3
3
|
class ConfigurationError < StandardError; end;
|
4
|
-
|
4
|
+
|
5
5
|
# Allow YAML configuration from config/cellect.yml
|
6
6
|
#
|
7
7
|
# development:
|
@@ -16,33 +16,33 @@ module Cellect
|
|
16
16
|
ensure_config_url config
|
17
17
|
connect_zookeeper config if load_zookeeper
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
private
|
21
|
-
|
21
|
+
|
22
22
|
def config_file
|
23
23
|
Rails.root.join 'config/cellect.yml'
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def ensure_config_file
|
27
27
|
return if File.exists?(config_file)
|
28
28
|
raise ConfigurationError.new 'No configuration file found. Create config/cellect.yml first'
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
def ensure_config_environment(yaml)
|
32
32
|
return if yaml[Rails.env].is_a?(Hash)
|
33
33
|
raise ConfigurationError.new "No configuration for #{ Rails.env } found"
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
def ensure_config_url(hash)
|
37
37
|
return if hash[:zk_url].present?
|
38
38
|
raise ConfigurationError.new "No Zookeeper URL provided for #{ Rails.env } environment"
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def connect_zookeeper(config)
|
42
42
|
Client.node_set config[:zk_url]
|
43
43
|
Client.connection = Connection.pool size: config.fetch(:pool_size, 100)
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
def load_zookeeper
|
47
47
|
!Client.mock_zookeeper?
|
48
48
|
rescue NoMethodError
|
data/lib/cellect/client.rb
CHANGED
@@ -4,31 +4,31 @@ module Cellect
|
|
4
4
|
module Client
|
5
5
|
require 'cellect/client/node_set'
|
6
6
|
require 'cellect/client/connection'
|
7
|
-
|
7
|
+
|
8
8
|
class << self
|
9
9
|
attr_accessor :connection, :_node_set
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
# Sets up the set of server nodes
|
13
13
|
def self.node_set(zk_url=nil)
|
14
14
|
self._node_set ||= NodeSet.supervise(zk_url)
|
15
15
|
_node_set.actors.first
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def self.ready?
|
19
19
|
node_set.ready?
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
# Selects a server for a user
|
23
23
|
def self.choose_host
|
24
24
|
node_set.nodes.values.sample
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
# Ensure a previously selected server is still available
|
28
28
|
def self.host_exists?(ip)
|
29
29
|
node_set.nodes.values.include? ip
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
if defined?(::Rails)
|
33
33
|
require 'cellect/client/railtie'
|
34
34
|
else
|
data/lib/cellect/node_set.rb
CHANGED
@@ -1,39 +1,39 @@
|
|
1
1
|
require 'zk'
|
2
|
-
require 'timeout'
|
3
2
|
|
4
3
|
module Cellect
|
5
4
|
class NodeSet
|
6
5
|
include Celluloid
|
7
|
-
|
6
|
+
ConnectionError = Class.new(StandardError)
|
7
|
+
|
8
8
|
attr_accessor :zk, :state
|
9
|
-
|
9
|
+
|
10
10
|
# Sets up the node set and starts connecting to ZooKeeper
|
11
11
|
def initialize(zk_url = nil)
|
12
12
|
@zk_url = zk_url
|
13
13
|
self.state = :initializing
|
14
14
|
after(0.001){ async.initialize_zk } # don't block waiting for ZK to connect
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
# Connect to ZooKeeper, setup this node, and change state
|
18
18
|
def initialize_zk
|
19
|
-
# don't let ZK hang the thread,
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
# don't let ZK hang the thread, timeout and check connection status
|
20
|
+
zk = ZK::Client.new zk_url, timeout: 0.5, chroot: '/cellect'
|
21
|
+
raise ConnectionError.new("Can't connect to ZK server.") unless zk.connected?
|
22
|
+
self.zk = zk
|
23
23
|
setup
|
24
24
|
self.state = :ready
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def ready?
|
28
28
|
state == :ready
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
protected
|
32
|
-
|
32
|
+
|
33
33
|
def zk_url
|
34
34
|
@zk_url || ENV.fetch('ZK_URL', 'localhost:2181')
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def setup
|
38
38
|
# Specialized in subclasses
|
39
39
|
end
|
data/lib/cellect/version.rb
CHANGED
data/lib/cellect.rb
CHANGED
@@ -3,85 +3,85 @@ require 'spec_helper'
|
|
3
3
|
module Cellect::Client
|
4
4
|
describe Connection do
|
5
5
|
let(:connection){ Cellect::Client.connection }
|
6
|
-
|
6
|
+
|
7
7
|
before(:each) do
|
8
8
|
allow(Cellect::Client.node_set).to receive(:nodes).and_return 'a' => '1', 'b' => '2'
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def should_send(action:, url:, to:)
|
12
12
|
expect(HTTP).to receive(:send).with(action, "http://#{ to }/#{ url }", socket_class: Celluloid::IO::TCPSocket).and_return(HTTP::Response.new(200, nil, nil, "{ \"this response\": \"intentionally blank\" }"))
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def should_broadcast(action:, url:)
|
16
16
|
[1, 2].each{ |i| should_send action: action, url: url, to: i }
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it 'should reload workflows' do
|
20
20
|
should_broadcast action: :post, url: 'workflows/random/reload'
|
21
21
|
connection.reload_workflow 'random'
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
it 'should delete workflows' do
|
25
25
|
should_broadcast action: :delete, url: 'workflows/random'
|
26
26
|
connection.delete_workflow 'random'
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
it 'should add subjects' do
|
30
30
|
should_broadcast action: :put, url: 'workflows/random/add?subject_id=123'
|
31
31
|
connection.add_subject 123, workflow_id: 'random'
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
it 'should add grouped subjects' do
|
35
35
|
should_broadcast action: :put, url: 'workflows/random/add?subject_id=123&group_id=321'
|
36
36
|
connection.add_subject 123, workflow_id: 'random', group_id: 321
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
it 'should add prioritized grouped subjects' do
|
40
40
|
should_broadcast action: :put, url: 'workflows/random/add?subject_id=123&group_id=321&priority=0.123'
|
41
41
|
connection.add_subject 123, workflow_id: 'random', group_id: 321, priority: 0.123
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
it 'should remove subjects' do
|
45
45
|
should_broadcast action: :put, url: 'workflows/random/remove?subject_id=123'
|
46
46
|
connection.remove_subject 123, workflow_id: 'random'
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
it 'should remove grouped subjects' do
|
50
50
|
should_broadcast action: :put, url: 'workflows/random/remove?subject_id=123&group_id=321'
|
51
51
|
connection.remove_subject 123, workflow_id: 'random', group_id: 321
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
it 'should load users' do
|
55
55
|
should_send action: :post, url: 'workflows/random/users/123/load', to: 1
|
56
56
|
connection.load_user user_id: 123, host: '1', workflow_id: 'random'
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
it 'should add seen subjects' do
|
60
60
|
should_send action: :put, url: 'workflows/random/users/123/add_seen?subject_id=456', to: 1
|
61
61
|
connection.add_seen subject_id: 456, host: '1', user_id: 123, workflow_id: 'random'
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
it 'should get subjects' do
|
65
65
|
should_send action: :get, url: 'workflows/random?user_id=1', to: 1
|
66
66
|
connection.get_subjects host: '1', workflow_id: 'random', user_id: 1
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
it 'should get grouped subjects' do
|
70
70
|
should_send action: :get, url: 'workflows/random?user_id=1&group_id=1&limit=10', to: 1
|
71
71
|
connection.get_subjects host: '1', workflow_id: 'random', user_id: 1, limit: 10, group_id: 1
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
context 'getting subjects' do
|
75
75
|
def get_subjects
|
76
76
|
connection.get_subjects host: '1', workflow_id: 'random', user_id: 1, limit: 10, group_id: 1
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
it 'should return subjects as an array' do
|
80
80
|
response = HTTP::Response.new 200, '1.1', nil, '[1, 2, 3, 4, 5]'
|
81
81
|
allow(HTTP).to receive(:send).and_return response
|
82
82
|
expect(get_subjects).to eq [1, 2, 3, 4, 5]
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
it 'should raise an error for unexpected responses' do
|
86
86
|
response = HTTP::Response.new 404, '1.1', nil, ''
|
87
87
|
allow(HTTP).to receive(:send).and_return response
|
@@ -4,7 +4,10 @@ module Cellect::Client
|
|
4
4
|
describe NodeSet do
|
5
5
|
it_behaves_like 'node set'
|
6
6
|
let(:node_set){ Cellect::Client.node_set }
|
7
|
-
|
7
|
+
|
8
|
+
#@note: node_set.nodes has state from intial code loading
|
9
|
+
# the above def which is really a cached celluloid actor from boot
|
10
|
+
# see Cellect::Client / Cellect::Server
|
8
11
|
it 'should update the node list when changing' do
|
9
12
|
begin
|
10
13
|
pass_until node_set, is: :ready
|
@@ -13,7 +16,6 @@ module Cellect::Client
|
|
13
16
|
break if node_set.nodes['node0000000001']
|
14
17
|
Thread.pass
|
15
18
|
end
|
16
|
-
|
17
19
|
expect(node_set.nodes['node0000000001']).to eq 'foo'
|
18
20
|
ensure
|
19
21
|
node_set.zk.delete '/nodes/node0000000001'
|
data/spec/spec_helper.rb
CHANGED
@@ -12,7 +12,6 @@ Bundler.require :test, :development
|
|
12
12
|
|
13
13
|
ENV['CELLECT_POOL_SIZE'] = '3'
|
14
14
|
SPAWN_ZK = !ENV['ZK_URL']
|
15
|
-
|
16
15
|
require 'pry'
|
17
16
|
require 'oj'
|
18
17
|
require './spec/support/zk_setup.rb'
|
@@ -32,14 +31,14 @@ RSpec.configure do |config|
|
|
32
31
|
config.filter_run :focus
|
33
32
|
config.order = 'random'
|
34
33
|
config.include CellectHelper
|
35
|
-
|
34
|
+
|
36
35
|
config.around(:each) do |example|
|
37
36
|
Celluloid.boot
|
38
37
|
example.run
|
39
38
|
Celluloid.shutdown
|
40
39
|
end
|
41
|
-
|
40
|
+
|
42
41
|
config.after(:suite) do
|
43
|
-
|
42
|
+
ZK_Setup.stop_zk
|
44
43
|
end
|
45
44
|
end
|
@@ -1,18 +1,18 @@
|
|
1
1
|
shared_examples_for 'node set' do
|
2
2
|
let(:node_set){ Cellect::NodeSet.new }
|
3
|
-
|
3
|
+
|
4
4
|
it 'should connect to zoo keeper' do
|
5
5
|
expect(node_set.zk).to be_nil
|
6
6
|
pass_until node_set, is: :ready
|
7
7
|
expect(node_set.zk).to be_connected
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
it 'should know the connection state' do
|
11
11
|
expect(node_set.state).to be :initializing
|
12
12
|
pass_until node_set, is: :ready
|
13
13
|
expect(node_set).to be_ready
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
it 'should accept a connection string' do
|
17
17
|
url_before = ENV['ZK_URL']
|
18
18
|
begin
|
@@ -2,30 +2,30 @@ shared_examples_for 'a set' do
|
|
2
2
|
it 'should convert to an Array' do
|
3
3
|
expect(set.to_a).to eq (1..5).to_a
|
4
4
|
end
|
5
|
-
|
5
|
+
|
6
6
|
it 'should add elements' do
|
7
7
|
set.add 100
|
8
8
|
expect(set.to_a).to include 100
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
it 'should remove elements' do
|
12
12
|
set.remove 1
|
13
13
|
set.to_a.should_not include 1
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
it 'should sample elements' do
|
17
17
|
expect(set.sample(2).length).to eq 2
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
it 'should not include removed elements in samples' do
|
21
21
|
set.remove 5
|
22
22
|
set.sample(5).should_not include 5
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
it 'should know how many elements it contains' do
|
26
26
|
expect{ set.add 100 }.to change{ set.size }.from(5).to 6
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
it 'should know if it contains an element' do
|
30
30
|
set.should_not include 100
|
31
31
|
set.add 100
|
@@ -1,23 +1,23 @@
|
|
1
1
|
shared_examples_for 'workflow' do |name|
|
2
2
|
let(:obj){ send name }
|
3
|
-
|
3
|
+
|
4
4
|
before(:each) do
|
5
5
|
Cellect::Server.adapter.load_workflow obj.name
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
it 'should add singleton instances to the registry' do
|
9
9
|
expect(obj.class[obj.name]).to be_a_kind_of Cellect::Server::Workflow
|
10
10
|
expect(obj.class[obj.name].object_id).to eq obj.class[obj.name].object_id
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
it 'should initialize empty' do
|
14
14
|
expect(obj.name).to be_a String
|
15
15
|
expect(obj.users).to be_a Hash
|
16
|
-
|
16
|
+
|
17
17
|
set_klass = obj.prioritized? ? DiffSet::PrioritySet : DiffSet::RandomSet
|
18
18
|
expect(obj.subjects).to be_a set_klass
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
it 'should provide a user lookup' do
|
22
22
|
expect(obj.user(1)).to be_a Cellect::Server::User
|
23
23
|
expect(obj.user(1).object_id).to eq obj.user(1).object_id
|
@@ -8,11 +8,11 @@ class SpecAdapter < Cellect::Server::Adapters::Default
|
|
8
8
|
fixtures.values_at(*names)
|
9
9
|
end
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def load_data_for(workflow_name)
|
13
13
|
fixtures.fetch(workflow_name, { }).fetch 'entries', []
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def fixtures
|
17
17
|
@fixtures ||= { }.tap do |fixtures|
|
18
18
|
Dir["#{ _fixture_path }/workflow_data/*.json"].collect do |f|
|
@@ -22,7 +22,7 @@ class SpecAdapter < Cellect::Server::Adapters::Default
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def user_fixtures
|
27
27
|
@user_fixtures ||= { }.tap do |user_fixtures|
|
28
28
|
Dir["#{ _fixture_path }/user_data/*.json"].sort.collect.with_index do |f, i|
|
@@ -33,14 +33,14 @@ class SpecAdapter < Cellect::Server::Adapters::Default
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def load_user(workflow_name, id)
|
38
38
|
user = user_fixtures[id]
|
39
39
|
user ? user[workflow_name] : user_fixtures['new_user'][workflow_name]
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
protected
|
43
|
-
|
43
|
+
|
44
44
|
def _fixture_path
|
45
45
|
File.expand_path File.join(__FILE__, '../../fixtures')
|
46
46
|
end
|
data/spec/support/zk_setup.rb
CHANGED
@@ -1,28 +1,51 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
1
|
+
module ZK_Setup
|
2
|
+
def self.start_zk(port=21811)
|
3
|
+
@port = port
|
4
|
+
if SPAWN_ZK
|
5
|
+
kill_old_zk_servers
|
6
|
+
remove_zk_data
|
7
|
+
server = ZK::Server.new do |config|
|
8
|
+
config.client_port = port
|
9
|
+
config.client_port_address = 'localhost'
|
10
|
+
config.force_sync = false
|
11
|
+
config.tick_time = 2000
|
12
|
+
config.init_limit = 10
|
13
|
+
config.sync_limit = 5
|
14
|
+
config.snap_count = 1000000
|
15
|
+
config.base_dir = zk_dir
|
16
|
+
end
|
17
|
+
server.run
|
18
|
+
@zk_server = server
|
19
|
+
ENV['ZK_URL'] = "localhost:#{port}"
|
20
|
+
end
|
17
21
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
|
23
|
+
def self.stop_zk
|
24
|
+
if SPAWN_ZK
|
25
|
+
@zk_server.shutdown
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.zk_dir
|
30
|
+
File.join CELLECT_ROOT, 'tmp/zookeeper'
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.zk_ok?
|
34
|
+
`echo ruok | nc 127.0.0.1 #{@port}`.chomp == 'imok'
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.kill_old_zk_servers
|
38
|
+
if zk_ok?
|
39
|
+
pid = `ps aux | grep -e 'Cellect[\/]tmp[\/]zookeeper'`.split[1]
|
40
|
+
puts "Killing rogue zookeeper process: #{ pid }..."
|
41
|
+
`kill -s TERM #{ pid }`
|
42
|
+
sleep 1
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.remove_zk_data
|
47
|
+
`rm -rf #{ zk_dir }; mkdir -p #{ zk_dir }`
|
24
48
|
end
|
25
|
-
|
26
|
-
`zkServer start #{ CELLECT_ZK_CONFIG } > /dev/null 2>&1`
|
27
|
-
ENV['ZK_URL'] = 'localhost:21811'
|
28
49
|
end
|
50
|
+
|
51
|
+
ZK_Setup.start_zk
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cellect-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Parrish
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: zk-server
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
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: rack-test
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -232,7 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
232
246
|
version: '0'
|
233
247
|
requirements: []
|
234
248
|
rubyforge_project:
|
235
|
-
rubygems_version: 2.
|
249
|
+
rubygems_version: 2.4.2
|
236
250
|
signing_key:
|
237
251
|
specification_version: 4
|
238
252
|
summary: ''
|