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: ''
         
     |