celluloid-presence 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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +51 -0
- data/Rakefile +10 -0
- data/lib/celluloid-presence/presence.rb +162 -0
- data/lib/celluloid-presence/service.rb +160 -0
- data/lib/celluloid-presence/version.rb +6 -0
- data/lib/celluloid-presence.rb +3 -0
- data/lib/dcell/registries/zk_presence_adapter.rb +152 -0
- metadata +79 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 83c3287a94c2f820bab2be50041e10183562379d
|
4
|
+
data.tar.gz: 5e94a2416dcaca6535a64291eb525b5117a8d338
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c90b5508fc1281b5f3713b87c9a980b89e9e46728db5efdd53ca782fe10393c560d78901a0b0707fcb154d6eb0320b314f4e84edaf81790e8296583210821eff
|
7
|
+
data.tar.gz: 979c29216afcd3a3d958f8ee6625cfb91e7bcedb47d45d75ffad5675e0b2de0a9a9ff82d9091552c1e14ebe129bc1e51917dd6fe70f0d10a7aa8d514029356bb
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
h1. Celluloid Presence
|
2
|
+
|
3
|
+
Start an instance of "ZooKeeper":http://zookeeper.apache.org/ on your server then run:
|
4
|
+
* OSX:
|
5
|
+
*
|
6
|
+
|
7
|
+
<pre><code class="ruby">
|
8
|
+
require 'rubygems'
|
9
|
+
require 'celluloid-presence'
|
10
|
+
|
11
|
+
Celluloid::Presence::ZkService.init :server => 'localhost'
|
12
|
+
Celluloid::Presence::ZkPresence.supervise_as :presence, :service_name => :presence
|
13
|
+
|
14
|
+
class Messaging
|
15
|
+
include Celluloid
|
16
|
+
include Celluloid::Notifications
|
17
|
+
|
18
|
+
def self.finalizer
|
19
|
+
:finalize
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(service_name)
|
23
|
+
@service_name = service_name
|
24
|
+
subscribe("#{@service_name}_nodes", :node_update)
|
25
|
+
end
|
26
|
+
|
27
|
+
def node_update(event, nodes)
|
28
|
+
p "\nNode list updated!"
|
29
|
+
nodes.each do |node|
|
30
|
+
p " -> #{Actor[@service_name].get(node)}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
|
38
|
+
def finalize
|
39
|
+
Actor[@service_name].terminate
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Messaging.run(:presence)
|
44
|
+
</code></pre>
|
45
|
+
|
46
|
+
|
47
|
+
h2. Start using it now
|
48
|
+
|
49
|
+
# Read the "Documentation":http://rubydoc.info/gems/celluloid-promise/Celluloid/Presence
|
50
|
+
# Then @gem install celluloid-presence@
|
51
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Celluloid
|
4
|
+
module Presence
|
5
|
+
class ZkPresence
|
6
|
+
include Celluloid
|
7
|
+
include Celluloid::Notifications
|
8
|
+
|
9
|
+
PREFIX ||= '/coPresence'
|
10
|
+
NODE_PREFIX ||= 'node-'
|
11
|
+
|
12
|
+
|
13
|
+
def self.finalizer
|
14
|
+
:finalize
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def initialize(options = {})
|
19
|
+
@env = options[:env] || 'production'
|
20
|
+
@base_path = options[:service_name].nil? ? "#{PREFIX}/#{@env}/default" : "#{PREFIX}/#{@env}/#{options[:service_name]}"
|
21
|
+
@base_path_sym = @base_path.to_sym
|
22
|
+
@node_path = nil # This is officially set in connect_setup
|
23
|
+
@service_name = options[:service_name] || :default
|
24
|
+
@nodes = []
|
25
|
+
|
26
|
+
if options[:node_address].nil?
|
27
|
+
use_ip_v4 = !options[:ip_v6] # IP v6 or IP v4 if using the default node data
|
28
|
+
@node_address = proc { ip_address(use_ip_v4) }
|
29
|
+
else
|
30
|
+
node_address = options[:node_address]
|
31
|
+
@node_address = proc { node_address.is_a?(Proc) ? node_address.call : node_address }
|
32
|
+
end
|
33
|
+
@last_known_address = nil
|
34
|
+
|
35
|
+
#
|
36
|
+
# These callbacks will be executed on a seperate thread
|
37
|
+
# Which is why we need to use notifications update state
|
38
|
+
#
|
39
|
+
zk.register(@base_path)
|
40
|
+
subscribe("zk_event_#{@base_path}", :zk_callback)
|
41
|
+
subscribe('zk_connected', :on_connected)
|
42
|
+
subscribe('zk_connecting', :on_connecting)
|
43
|
+
|
44
|
+
on_connected if zk.connected?
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
#
|
49
|
+
# Provides the list of known nodes
|
50
|
+
#
|
51
|
+
attr_reader :nodes
|
52
|
+
|
53
|
+
|
54
|
+
#
|
55
|
+
# This informs us of changes to the list of base path's children
|
56
|
+
#
|
57
|
+
def zk_callback(event_name, event)
|
58
|
+
#p "EVENT OCUURED #{event.event_name} #{event.path}"
|
59
|
+
if event.node_child? # We are only listening to child events so we only need to handle these
|
60
|
+
begin
|
61
|
+
@nodes = zk.children(@base_path, :watch => true) # re-set watch
|
62
|
+
update_node_information
|
63
|
+
rescue ZK::Exceptions::NoNode # Technically this shouldn't happen unless someone deleted our base path
|
64
|
+
on_connected if zk.connected?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# This informs us of a new connection being established with zookeeper
|
71
|
+
#
|
72
|
+
def on_connected(event = nil)
|
73
|
+
address = @node_address.call
|
74
|
+
if @node_path.nil? or not zk.exists?(@node_path) # Create presence node as it doesn't exist
|
75
|
+
#p 'node re-created'
|
76
|
+
@last_known_address = address
|
77
|
+
connect_setup
|
78
|
+
elsif @last_known_address != address # Recreate existing presence node as our IP changed
|
79
|
+
#p 'node ip_changed, recreating'
|
80
|
+
zk.async.ensure(:delete, @node_path)
|
81
|
+
@last_known_address = address
|
82
|
+
connect_setup
|
83
|
+
else # Else our node presence information is accurate, lets get the latest list
|
84
|
+
@nodes = zk.children(@base_path, :watch => true)
|
85
|
+
end
|
86
|
+
|
87
|
+
update_node_information # inform listeners of a node list update
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# This informs us that we've been disconnected from zookeeper
|
92
|
+
#
|
93
|
+
def on_connecting event
|
94
|
+
publish("#{@service_name}_nodes_stale")
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Returns the value of a node
|
99
|
+
#
|
100
|
+
def get(node_id)
|
101
|
+
result, _ = zk.get("#{@base_path}/#{node_id}")
|
102
|
+
result
|
103
|
+
rescue ZK::Exceptions::NoNode
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# Returns the name of this node
|
108
|
+
#
|
109
|
+
def name
|
110
|
+
@node_path.split('/')[-1]
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
|
117
|
+
#
|
118
|
+
# Shortcut to the zookeeper service
|
119
|
+
#
|
120
|
+
def zk
|
121
|
+
Actor[:zk_service]
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# creates the presence node
|
126
|
+
#
|
127
|
+
def connect_setup
|
128
|
+
zk.mkdir_p @base_path
|
129
|
+
@node_path = zk.create "#{@base_path}/#{NODE_PREFIX}", @last_known_address, :sequence => true, :ephemeral => true
|
130
|
+
@nodes = zk.children @base_path, :watch => true
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# Pushes an updated node list to subscribers
|
135
|
+
#
|
136
|
+
def update_node_information
|
137
|
+
publish("#{@service_name}_nodes", @nodes)
|
138
|
+
end
|
139
|
+
|
140
|
+
#
|
141
|
+
# Grabs a valid IP address
|
142
|
+
#
|
143
|
+
def ip_address(ip_v4)
|
144
|
+
ip = if ip_v4
|
145
|
+
Socket.ip_address_list.detect {|a| a.ipv4? && !a.ipv4_loopback?}
|
146
|
+
else
|
147
|
+
Socket.ip_address_list.detect {|a| !a.ipv4? && !(a.ipv6_linklocal? || a.ipv6_loopback?)}
|
148
|
+
end
|
149
|
+
return ip.ip_address unless ip.nil?
|
150
|
+
nil
|
151
|
+
end
|
152
|
+
|
153
|
+
#
|
154
|
+
# On termination make sure zookeeper is updated
|
155
|
+
#
|
156
|
+
def finalize
|
157
|
+
zk.async.unregister(@base_path)
|
158
|
+
zk.async.ensure(:delete, @node_path) unless @node_path.nil?
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'zk'
|
2
|
+
|
3
|
+
module Celluloid
|
4
|
+
module Presence
|
5
|
+
class ZkService
|
6
|
+
include Celluloid
|
7
|
+
include Celluloid::Notifications
|
8
|
+
|
9
|
+
DEFAULT_PORT ||= 2181
|
10
|
+
@@zk ||= nil # The single zookeeper instance
|
11
|
+
@@registry ||= {} # Paths we are interested in receiving events from
|
12
|
+
@@registry_count ||= {} # Listener counts (for unregistering)
|
13
|
+
@@ensure ||= [] # Tasks we want to ensure are completed (even when disconnected)
|
14
|
+
@@connected ||= false # We'll maintain our own connected state
|
15
|
+
|
16
|
+
|
17
|
+
#
|
18
|
+
# Optional init function to supervise this actor
|
19
|
+
#
|
20
|
+
def self.init(options)
|
21
|
+
ZkService.supervise_as :zk_service, options
|
22
|
+
end
|
23
|
+
|
24
|
+
# Create a single connection to Zookeeper that persists through Actor crashes
|
25
|
+
#
|
26
|
+
# servers: a list of Zookeeper servers to connect to. Each server in the
|
27
|
+
# list has a host/port configuration
|
28
|
+
def initialize(options)
|
29
|
+
@@zk ||= begin
|
30
|
+
Fanout.supervise_as :notifications_fanout if Actor[:notifications_fanout].nil?
|
31
|
+
|
32
|
+
# Let them specify a single server instead of many
|
33
|
+
servers = options[:server].nil? ? options[:servers] : [options[:server]]
|
34
|
+
raise "no Zookeeper servers given" unless servers
|
35
|
+
|
36
|
+
# Add the default Zookeeper port unless specified
|
37
|
+
servers.map! do |server|
|
38
|
+
if server[/:\d+$/]
|
39
|
+
server
|
40
|
+
else
|
41
|
+
"#{server}:#{DEFAULT_PORT}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
ZK.new(*servers) do |zk|
|
46
|
+
zk.on_connecting &proc { Actor[:zk_service].async.on_connecting }
|
47
|
+
zk.on_connected &proc { Actor[:zk_service].async.on_connected }
|
48
|
+
end
|
49
|
+
end.tap do |zk|
|
50
|
+
@@connected = zk.connected?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Called once a connection is made to the zookeeper cluster
|
56
|
+
# Runs any impending ensures before informing any subscribed actors
|
57
|
+
#
|
58
|
+
def on_connected
|
59
|
+
@@connected = true
|
60
|
+
while not @@ensure.empty?
|
61
|
+
func = @@ensure.shift
|
62
|
+
ensured func[0], *func[1] # func[0] == function name, func[1] == arguments
|
63
|
+
end
|
64
|
+
publish('zk_connected')
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Called on disconnect from zookeeper
|
69
|
+
# Might be that the zookeeper node crashed or zookeeper is down, may not effect any other connections
|
70
|
+
#
|
71
|
+
def on_connecting
|
72
|
+
@@connected = false
|
73
|
+
publish('zk_connecting')
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Publishes any zookeeper events that have been registered
|
78
|
+
#
|
79
|
+
def event_callback(path, event)
|
80
|
+
publish("zk_event_#{path}", event)
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# Uses a closure to cleanly pull the zookeeper event back into the protection of celluloid
|
85
|
+
#
|
86
|
+
def register(path)
|
87
|
+
path = path.to_sym
|
88
|
+
if @@registry[path].nil?
|
89
|
+
callback = proc { |event| Actor[:zk_service].async.event_callback(path, event) }
|
90
|
+
@@registry[path] = @@zk.register(path.to_s, &callback)
|
91
|
+
end
|
92
|
+
@@registry_count[path] = (@@registry_count[path] || 0) + 1
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# unsubscribes from zookeeper events once there are no more listeners
|
97
|
+
#
|
98
|
+
def unregister(path)
|
99
|
+
path = path.to_sym
|
100
|
+
if @@registry[path]
|
101
|
+
@@registry_count[path] -= 1
|
102
|
+
if @@registry_count[path] <= 0
|
103
|
+
sub = @@registry.delete(path)
|
104
|
+
sub.unsubscribe
|
105
|
+
@@registry_count.delete(path)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# Our abstracted connected status to avoid race conditions
|
112
|
+
#
|
113
|
+
def connected?
|
114
|
+
@@connected
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Ensures important requests are followed through in the case of disconnect / reconnect
|
119
|
+
# Ignores request if the node does not exist
|
120
|
+
# USE SPARINGLY
|
121
|
+
#
|
122
|
+
def ensure(func, *args)
|
123
|
+
if connected?
|
124
|
+
ensured(func, *args)
|
125
|
+
else
|
126
|
+
@@ensure.push [func, args]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
#
|
132
|
+
# Proxy the following functions
|
133
|
+
#
|
134
|
+
# Automatically creates a callable function for each command
|
135
|
+
# http://blog.jayfields.com/2007/10/ruby-defining-class-methods.html
|
136
|
+
# http://blog.jayfields.com/2008/02/ruby-dynamically-define-method.html
|
137
|
+
#
|
138
|
+
SAFE_OPS ||= [:get, :children, :create, :mkdir_p, :delete, :stat, :exists?, :set, :rm_rf]
|
139
|
+
SAFE_OPS.each do |func|
|
140
|
+
define_method func do |*args|
|
141
|
+
begin
|
142
|
+
@@zk.send func, *args if connected?
|
143
|
+
rescue Zookeeper::Exceptions::NotConnected
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
|
152
|
+
def ensured(func, *args)
|
153
|
+
@@zk.send func, *args
|
154
|
+
rescue Zookeeper::Exceptions::NotConnected
|
155
|
+
@@ensure << [func, args]
|
156
|
+
rescue ZK::Exceptions::NoNode
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'celluloid-presence'
|
2
|
+
|
3
|
+
|
4
|
+
module DCell
|
5
|
+
module Registry
|
6
|
+
class ZkPresenceAdapter
|
7
|
+
def initialize(options)
|
8
|
+
Celluloid::Presence::ZkService.init options
|
9
|
+
|
10
|
+
@node_registry = NodeRegistry.new(options)
|
11
|
+
@global_registry = GlobalRegistry.new(:zk_service, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
class NodeRegistry
|
16
|
+
include Celluloid
|
17
|
+
include Celluloid::Notifications
|
18
|
+
|
19
|
+
def initialize(options)
|
20
|
+
@mutex = Mutex.new
|
21
|
+
@current_address = nil
|
22
|
+
|
23
|
+
Celluloid::Presence::ZkPresence.supervise_as :dcell_presence, {
|
24
|
+
:service_name => :dcell_presence,
|
25
|
+
:node_address => proc { @mutex.synchronize { @current_address } },
|
26
|
+
:env => options[:env] || 'production'
|
27
|
+
}
|
28
|
+
|
29
|
+
@service_name = :dcell_presence
|
30
|
+
@directory = {} # node_name => address
|
31
|
+
@mapping = {} # zk_path => node_name
|
32
|
+
|
33
|
+
subscribe("#{@service_name}_nodes", :node_update)
|
34
|
+
|
35
|
+
@nodes = []
|
36
|
+
update_directory(presence.nodes)
|
37
|
+
end
|
38
|
+
|
39
|
+
def get(node_id)
|
40
|
+
@directory[node_id]
|
41
|
+
end
|
42
|
+
|
43
|
+
def nodes
|
44
|
+
@directory.keys
|
45
|
+
end
|
46
|
+
|
47
|
+
def node_update(event, nodes)
|
48
|
+
update_directory(nodes)
|
49
|
+
end
|
50
|
+
|
51
|
+
def set(node_id, addr)
|
52
|
+
@mutex.synchronize {
|
53
|
+
@current_address = Marshal.dump [node_id, addr]
|
54
|
+
}
|
55
|
+
presence.on_connected # This causes an address update on zookeeper
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
|
62
|
+
def update_directory(new_list)
|
63
|
+
unsubscribe = @nodes - new_list # TODO:: use sets here instead of arrays for speed
|
64
|
+
subscribe = new_list - @nodes
|
65
|
+
|
66
|
+
unsubscribe.each do |node|
|
67
|
+
node_name = @mapping.delete(node)
|
68
|
+
@directory.delete(node_name)
|
69
|
+
end
|
70
|
+
|
71
|
+
subscribe.each do |node|
|
72
|
+
value = presence.get(node)
|
73
|
+
if value.nil?
|
74
|
+
@nodes.delete value
|
75
|
+
else
|
76
|
+
begin
|
77
|
+
info = Marshal.load value
|
78
|
+
@mapping[node] = info[0]
|
79
|
+
@directory[info[0]] = info[1]
|
80
|
+
rescue
|
81
|
+
@nodes.delete value
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
@nodes = new_list
|
87
|
+
end
|
88
|
+
|
89
|
+
def presence
|
90
|
+
::Celluloid::Actor[@service_name]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def clear_nodes; end # This is now self maintaining hence no op
|
95
|
+
def get_node(node_id); @node_registry.get(node_id) end
|
96
|
+
def nodes; @node_registry.nodes end
|
97
|
+
def set_node(node_id, addr); @node_registry.set(node_id, addr) end
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
class GlobalRegistry
|
102
|
+
PREFIX = "/dcell_global"
|
103
|
+
|
104
|
+
def initialize(service_name, options)
|
105
|
+
options = options.inject({}) { |h,(k,v)| h[k.to_s] = v; h }
|
106
|
+
|
107
|
+
@service_name = service_name
|
108
|
+
@env = options['env'] || 'production'
|
109
|
+
@base_path = "#{PREFIX}/#{@env}"
|
110
|
+
end
|
111
|
+
|
112
|
+
def get(key)
|
113
|
+
value, _ = zk.get "#{@base_path}/#{key}"
|
114
|
+
Marshal.load value
|
115
|
+
rescue ZK::Exceptions::NoNode
|
116
|
+
end
|
117
|
+
|
118
|
+
# Set a global value
|
119
|
+
def set(key, value)
|
120
|
+
path = "#{@base_path}/#{key}"
|
121
|
+
string = Marshal.dump value
|
122
|
+
|
123
|
+
zk.set path, string
|
124
|
+
rescue ZK::Exceptions::NoNode
|
125
|
+
zk.create path, string
|
126
|
+
end
|
127
|
+
|
128
|
+
# The keys to all globals in the system
|
129
|
+
def global_keys
|
130
|
+
zk.children(@base_path)
|
131
|
+
end
|
132
|
+
|
133
|
+
def clear
|
134
|
+
zk.rm_rf @base_path
|
135
|
+
zk.mkdir_p @base_path
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
def zk
|
141
|
+
Celluloid::Actor[@service_name]
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
def clear_globals; @global_registry.clear end
|
147
|
+
def get_global(key); @global_registry.get(key) end
|
148
|
+
def set_global(key, value); @global_registry.set(key, value) end
|
149
|
+
def global_keys; @global_registry.global_keys end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: celluloid-presence
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stephen von Takach
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-03-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: celluloid
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Node presence using ZooKeeper for celluloid services
|
42
|
+
email:
|
43
|
+
- steve@cotag.me
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- lib/celluloid-presence/presence.rb
|
49
|
+
- lib/celluloid-presence/service.rb
|
50
|
+
- lib/celluloid-presence/version.rb
|
51
|
+
- lib/celluloid-presence.rb
|
52
|
+
- lib/dcell/registries/zk_presence_adapter.rb
|
53
|
+
- MIT-LICENSE
|
54
|
+
- Rakefile
|
55
|
+
- README.textile
|
56
|
+
homepage: https://github.com/cotag/celluloid-presence
|
57
|
+
licenses: []
|
58
|
+
metadata: {}
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 2.0.0
|
76
|
+
signing_key:
|
77
|
+
specification_version: 4
|
78
|
+
summary: Node presence using ZooKeeper for celluloid services
|
79
|
+
test_files: []
|