rightscale-nanite-dev 0.4.1.11 → 0.4.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -3
- data/lib/nanite.rb +1 -1
- data/lib/nanite/agent.rb +8 -1
- data/lib/nanite/cluster.rb +29 -24
- data/lib/nanite/local_state.rb +18 -14
- data/lib/nanite/mapper.rb +5 -3
- data/lib/nanite/packets.rb +39 -14
- data/lib/nanite/redis_tag_store.rb +6 -20
- data/lib/nanite/security/certificate.rb +3 -1
- data/lib/nanite/security/secure_serializer.rb +5 -3
- data/lib/nanite/state.rb +4 -14
- metadata +6 -7
data/Rakefile
CHANGED
data/lib/nanite.rb
CHANGED
@@ -39,7 +39,7 @@ require 'nanite/security/static_certificate_store'
|
|
39
39
|
require 'nanite/serializer'
|
40
40
|
|
41
41
|
module Nanite
|
42
|
-
VERSION = '0.4.1.
|
42
|
+
VERSION = '0.4.1.15' unless defined?(Nanite::VERSION)
|
43
43
|
|
44
44
|
class MapperNotRunning < StandardError; end
|
45
45
|
|
data/lib/nanite/agent.rb
CHANGED
@@ -5,7 +5,7 @@ module Nanite
|
|
5
5
|
include ConsoleHelper
|
6
6
|
include DaemonizeHelper
|
7
7
|
|
8
|
-
attr_reader :identity, :options, :serializer, :dispatcher, :registry, :amq, :tags
|
8
|
+
attr_reader :identity, :options, :serializer, :dispatcher, :registry, :amq, :tags, :callbacks
|
9
9
|
attr_accessor :status_proc
|
10
10
|
|
11
11
|
DEFAULT_OPTIONS = COMMON_DEFAULT_OPTIONS.merge({
|
@@ -74,6 +74,10 @@ module Nanite
|
|
74
74
|
# this defaults to 5672, port used by some widely
|
75
75
|
# used AMQP brokers (RabbitMQ and ZeroMQ)
|
76
76
|
#
|
77
|
+
# callback : Hash of proc objects defining well known callbacks
|
78
|
+
# Currently only the :exception callback is supported
|
79
|
+
# This block gets called whenever a packet generates an exception
|
80
|
+
#
|
77
81
|
# On start Nanite reads config.yml, so it is common to specify
|
78
82
|
# options in the YAML file. However, when both Ruby code options
|
79
83
|
# and YAML file specify option, Ruby code options take precedence.
|
@@ -166,6 +170,8 @@ module Nanite
|
|
166
170
|
File.open(File.expand_path(File.join(@options[:root], 'config.yml')), 'w') do |fd|
|
167
171
|
fd.write(YAML.dump(custom_config.merge(:identity => token)))
|
168
172
|
end
|
173
|
+
|
174
|
+
@callbacks = options[:callbacks]
|
169
175
|
end
|
170
176
|
|
171
177
|
def load_actors
|
@@ -224,6 +230,7 @@ module Nanite
|
|
224
230
|
receive(serializer.load(msg))
|
225
231
|
rescue Exception => e
|
226
232
|
Nanite::Log.error("RECV #{e.message}")
|
233
|
+
callbacks[:exception].call(e, msg, self) rescue nil if callbacks[:exception]
|
227
234
|
end
|
228
235
|
end
|
229
236
|
end
|
data/lib/nanite/cluster.rb
CHANGED
@@ -18,9 +18,9 @@ module Nanite
|
|
18
18
|
end
|
19
19
|
|
20
20
|
# determine which nanites should receive the given request
|
21
|
-
def targets_for(request)
|
21
|
+
def targets_for(request, include_timed_out)
|
22
22
|
return [request.target] if request.target
|
23
|
-
__send__(request.selector, request
|
23
|
+
__send__(request.selector, request, include_timed_out)
|
24
24
|
end
|
25
25
|
|
26
26
|
# adds nanite to nanites map: key is nanite's identity
|
@@ -71,7 +71,7 @@ module Nanite
|
|
71
71
|
old_target = request.target
|
72
72
|
request.target = target unless target == 'mapper-offline'
|
73
73
|
if @security.authorize_request(request)
|
74
|
-
Nanite::Log.info("SEND #{request.to_s([:from, :
|
74
|
+
Nanite::Log.info("SEND #{request.to_s([:from, :scope, :tags, :target])}")
|
75
75
|
amq.queue(target).publish(serializer.dump(request), :persistent => request.persistent)
|
76
76
|
else
|
77
77
|
Nanite::Log.warn("RECV NOT AUTHORIZED #{request.to_s}")
|
@@ -100,12 +100,12 @@ module Nanite
|
|
100
100
|
|
101
101
|
# forward request coming from agent
|
102
102
|
def handle_request(request)
|
103
|
-
Nanite::Log.info("RECV #{request.to_s([:from, :
|
103
|
+
Nanite::Log.info("RECV #{request.to_s([:from, :scope, :target, :tags])}") unless Nanite::Log.level == :debug
|
104
104
|
Nanite::Log.debug("RECV #{request.to_s}")
|
105
105
|
case request
|
106
106
|
when Push
|
107
107
|
mapper.send_push(request)
|
108
|
-
|
108
|
+
when Request
|
109
109
|
intm_handler = lambda do |result, job|
|
110
110
|
result = IntermediateMessage.new(request.token, job.request.from, mapper.identity, nil, result)
|
111
111
|
forward_response(result, request.persistent)
|
@@ -120,6 +120,10 @@ module Nanite
|
|
120
120
|
if ok == false
|
121
121
|
forward_response(result, request.persistent)
|
122
122
|
end
|
123
|
+
when TagQuery
|
124
|
+
results = nanites.nanites_for(request)
|
125
|
+
result = Result.new(request.token, request.from, results, mapper.identity)
|
126
|
+
forward_response(result, request.persistent)
|
123
127
|
end
|
124
128
|
end
|
125
129
|
|
@@ -130,37 +134,38 @@ module Nanite
|
|
130
134
|
end
|
131
135
|
|
132
136
|
# returns least loaded nanite that provides given service
|
133
|
-
def least_loaded(
|
134
|
-
candidates = nanites_providing(
|
137
|
+
def least_loaded(request, include_timed_out)
|
138
|
+
candidates = nanites_providing(request, include_timed_out)
|
135
139
|
return [] if candidates.empty?
|
136
|
-
|
137
|
-
[
|
140
|
+
res = candidates.to_a.min { |a, b| a[1][:status] <=> b[1][:status] }
|
141
|
+
[res[0]]
|
138
142
|
end
|
139
143
|
|
140
144
|
# returns all nanites that provide given service
|
141
|
-
|
142
|
-
|
145
|
+
# potentially including timed out agents
|
146
|
+
def all(request, include_timed_out)
|
147
|
+
nanites_providing(request, include_timed_out).keys
|
143
148
|
end
|
144
149
|
|
145
150
|
# returns a random nanite
|
146
|
-
def random(
|
147
|
-
candidates = nanites_providing(
|
151
|
+
def random(request, include_timed_out)
|
152
|
+
candidates = nanites_providing(request, include_timed_out)
|
148
153
|
return [] if candidates.empty?
|
149
|
-
|
150
|
-
[candidates[rand(candidates.size)]]
|
154
|
+
[candidates.keys[rand(candidates.size)]]
|
151
155
|
end
|
152
156
|
|
153
157
|
# selects next nanite that provides given service
|
154
158
|
# using round robin rotation
|
155
|
-
def rr(
|
159
|
+
def rr(request, include_timed_out)
|
156
160
|
@last ||= {}
|
161
|
+
service = request.type
|
157
162
|
@last[service] ||= 0
|
158
|
-
candidates = nanites_providing(
|
163
|
+
candidates = nanites_providing(request, include_timed_out)
|
159
164
|
return [] if candidates.empty?
|
160
165
|
@last[service] = 0 if @last[service] >= candidates.size
|
161
|
-
|
166
|
+
key = candidates.keys[@last[service]]
|
162
167
|
@last[service] += 1
|
163
|
-
[
|
168
|
+
[key]
|
164
169
|
end
|
165
170
|
|
166
171
|
def timed_out?(nanite)
|
@@ -168,10 +173,10 @@ module Nanite
|
|
168
173
|
end
|
169
174
|
|
170
175
|
# returns all nanites that provide the given service
|
171
|
-
def nanites_providing(
|
172
|
-
nanites.nanites_for(
|
173
|
-
if res = timed_out?(
|
174
|
-
Nanite::Log.debug("Ignoring timed out nanite #{nanite
|
176
|
+
def nanites_providing(request, include_timed_out)
|
177
|
+
nanites.nanites_for(request).delete_if do |nanite, info|
|
178
|
+
if res = !include_timed_out && timed_out?(info)
|
179
|
+
Nanite::Log.debug("Ignoring timed out nanite #{nanite} in target selection - last seen at #{info[:timestamp]}")
|
175
180
|
end
|
176
181
|
res
|
177
182
|
end
|
@@ -191,7 +196,7 @@ module Nanite
|
|
191
196
|
handle_ping(ping)
|
192
197
|
rescue Exception => e
|
193
198
|
Nanite::Log.error("RECV [ping] #{e.message}")
|
194
|
-
callbacks[:exception].call(e,
|
199
|
+
callbacks[:exception].call(e, ping, mapper) rescue nil if callbacks[:exception]
|
195
200
|
end
|
196
201
|
end
|
197
202
|
hb_fanout = amq.fanout('heartbeat', :durable => true)
|
data/lib/nanite/local_state.rb
CHANGED
@@ -6,28 +6,32 @@ module Nanite
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
def nanites_for(request)
|
10
|
+
tags = request.tags
|
11
|
+
service = request.service
|
12
|
+
if service
|
13
|
+
nanites = reject { |_, state| !state[:services].include?(service) }
|
14
|
+
else
|
15
|
+
nanites = self
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
nanites = select { |name, state| state[:services].include?(service) }
|
20
|
-
unless tags.empty?
|
21
|
-
nanites.select { |a, b| !(b[:tags] & tags).empty? }
|
18
|
+
if tags.nil? || tags.empty?
|
19
|
+
service ? nanites : {}
|
22
20
|
else
|
23
|
-
nanites
|
24
|
-
end
|
21
|
+
nanites.reject { |_, state| (state[:tags] & tags).empty? }
|
22
|
+
end
|
25
23
|
end
|
26
24
|
|
27
25
|
def update_status(name, status)
|
28
26
|
self[name].update(:status => status, :timestamp => Time.now.utc.to_i)
|
29
27
|
end
|
30
28
|
|
29
|
+
def update_tags(name, new_tags, obsolete_tags)
|
30
|
+
prev_tags = self[name] && self[name][:tags]
|
31
|
+
updated_tags = (new_tags || []) + (prev_tags || []) - (obsolete_tags || [])
|
32
|
+
self[name].update(:tags => updated_tags.uniq)
|
33
|
+
end
|
34
|
+
|
31
35
|
private
|
32
36
|
|
33
37
|
def all(key)
|
data/lib/nanite/mapper.rb
CHANGED
@@ -195,7 +195,7 @@ module Nanite
|
|
195
195
|
def send_request(request, opts = {}, &blk)
|
196
196
|
request.reply_to = identity
|
197
197
|
intm_handler = opts.delete(:intermediate_handler)
|
198
|
-
targets = cluster.targets_for(request)
|
198
|
+
targets = cluster.targets_for(request, include_timed_out=false)
|
199
199
|
if !targets.empty?
|
200
200
|
job = job_warden.new_job(request, targets, intm_handler, blk)
|
201
201
|
cluster.route(request, job.targets)
|
@@ -235,7 +235,8 @@ module Nanite
|
|
235
235
|
end
|
236
236
|
|
237
237
|
def send_push(push, opts = {})
|
238
|
-
|
238
|
+
include_timed_out = push.selector == :all
|
239
|
+
targets = cluster.targets_for(push, include_timed_out)
|
239
240
|
if !targets.empty?
|
240
241
|
cluster.route(push, targets)
|
241
242
|
true
|
@@ -270,7 +271,8 @@ module Nanite
|
|
270
271
|
offline_queue = amq.queue('mapper-offline', :durable => true)
|
271
272
|
offline_queue.subscribe(:ack => true) do |info, deliverable|
|
272
273
|
deliverable = serializer.load(deliverable)
|
273
|
-
|
274
|
+
include_timed_out = deliverable.is_a?(Push) && deliverable.selector == :all
|
275
|
+
targets = cluster.targets_for(deliverable, include_timed_out)
|
274
276
|
unless targets.empty?
|
275
277
|
info.ack
|
276
278
|
if deliverable.kind_of?(Request)
|
data/lib/nanite/packets.rb
CHANGED
@@ -113,7 +113,7 @@ module Nanite
|
|
113
113
|
#
|
114
114
|
# Options:
|
115
115
|
# from is sender identity
|
116
|
-
#
|
116
|
+
# scope define behavior that should be used to resolve tag based routing
|
117
117
|
# token is a generated request id that mapper uses to identify replies
|
118
118
|
# reply_to is identity of the node actor replies to, usually a mapper itself
|
119
119
|
# selector is the selector used to route the request
|
@@ -121,7 +121,7 @@ module Nanite
|
|
121
121
|
# persistent signifies if this request should be saved to persistent storage by the AMQP broker
|
122
122
|
class Request < Packet
|
123
123
|
|
124
|
-
attr_accessor :from, :
|
124
|
+
attr_accessor :from, :scope, :payload, :type, :token, :reply_to, :selector, :target, :persistent, :tags
|
125
125
|
|
126
126
|
DEFAULT_OPTIONS = {:selector => :least_loaded}
|
127
127
|
|
@@ -131,7 +131,7 @@ module Nanite
|
|
131
131
|
@payload = payload
|
132
132
|
@size = size
|
133
133
|
@from = opts[:from]
|
134
|
-
@
|
134
|
+
@scope = opts[:scope]
|
135
135
|
@token = opts[:token]
|
136
136
|
@reply_to = opts[:reply_to]
|
137
137
|
@selector = opts[:selector]
|
@@ -142,9 +142,9 @@ module Nanite
|
|
142
142
|
|
143
143
|
def self.json_create(o)
|
144
144
|
i = o['data']
|
145
|
-
new(i['type'], i['payload'], { :from
|
146
|
-
:token => i['token'], :reply_to => i['reply_to'],
|
147
|
-
:selector => i['selector'], :target => i['target'],
|
145
|
+
new(i['type'], i['payload'], { :from => i['from'], :scope => i['scope'],
|
146
|
+
:token => i['token'], :reply_to => i['reply_to'],
|
147
|
+
:selector => i['selector'], :target => i['target'],
|
148
148
|
:persistent => i['persistent'], :tags => i['tags'] },
|
149
149
|
o['size'])
|
150
150
|
end
|
@@ -152,7 +152,7 @@ module Nanite
|
|
152
152
|
def to_s(filter=nil)
|
153
153
|
log_msg = "#{super} <#{token}> #{type}"
|
154
154
|
log_msg += " from #{id_to_s(from)}" if filter.nil? || filter.include?(:from)
|
155
|
-
log_msg += "
|
155
|
+
log_msg += " with scope #{scope}" if scope && (filter.nil? || filter.include?(:scope))
|
156
156
|
log_msg += " to #{id_to_s(target)}" if target && (filter.nil? || filter.include?(:target))
|
157
157
|
log_msg += ", reply_to #{id_to_s(reply_to)}" if reply_to && (filter.nil? || filter.include?(:reply_to))
|
158
158
|
log_msg += ", tags #{tags.inspect}" if tags && !tags.empty? && (filter.nil? || filter.include?(:tags))
|
@@ -170,14 +170,14 @@ module Nanite
|
|
170
170
|
#
|
171
171
|
# Options:
|
172
172
|
# from is sender identity
|
173
|
-
#
|
173
|
+
# scope define behavior that should be used to resolve tag based routing
|
174
174
|
# token is a generated request id that mapper uses to identify replies
|
175
175
|
# selector is the selector used to route the request
|
176
176
|
# target is the target nanite for the request
|
177
177
|
# persistent signifies if this request should be saved to persistent storage by the AMQP broker
|
178
178
|
class Push < Packet
|
179
179
|
|
180
|
-
attr_accessor :from, :
|
180
|
+
attr_accessor :from, :scope, :payload, :type, :token, :selector, :target, :persistent, :tags
|
181
181
|
|
182
182
|
DEFAULT_OPTIONS = {:selector => :least_loaded}
|
183
183
|
|
@@ -187,7 +187,7 @@ module Nanite
|
|
187
187
|
@payload = payload
|
188
188
|
@size = size
|
189
189
|
@from = opts[:from]
|
190
|
-
@
|
190
|
+
@scope = opts[:scope]
|
191
191
|
@token = opts[:token]
|
192
192
|
@selector = opts[:selector]
|
193
193
|
@target = opts[:target]
|
@@ -197,9 +197,9 @@ module Nanite
|
|
197
197
|
|
198
198
|
def self.json_create(o)
|
199
199
|
i = o['data']
|
200
|
-
new(i['type'], i['payload'], { :from => i['from'], :
|
201
|
-
:token => i['token'], :selector => i['selector'],
|
202
|
-
:target => i['target'], :persistent => i['persistent'],
|
200
|
+
new(i['type'], i['payload'], { :from => i['from'], :scope => i['scope'],
|
201
|
+
:token => i['token'], :selector => i['selector'],
|
202
|
+
:target => i['target'], :persistent => i['persistent'],
|
203
203
|
:tags => i['tags'] },
|
204
204
|
o['size'])
|
205
205
|
end
|
@@ -207,7 +207,7 @@ module Nanite
|
|
207
207
|
def to_s(filter=nil)
|
208
208
|
log_msg = "#{super} <#{token}> #{type}"
|
209
209
|
log_msg += " from #{id_to_s(from)}" if filter.nil? || filter.include?(:from)
|
210
|
-
log_msg += "
|
210
|
+
log_msg += " with scope #{scope}" if scope && (filter.nil? || filter.include?(:scope))
|
211
211
|
log_msg += ", target #{id_to_s(target)}" if target && (filter.nil? || filter.include?(:target))
|
212
212
|
log_msg += ", tags #{tags.inspect}" if tags && !tags.empty? && (filter.nil? || filter.include?(:tags))
|
213
213
|
log_msg += ", payload #{payload.inspect}" if filter.nil? || filter.include?(:payload)
|
@@ -215,6 +215,31 @@ module Nanite
|
|
215
215
|
end
|
216
216
|
end
|
217
217
|
|
218
|
+
# Tag query: retrieve agent ids with associated tags that match given tags
|
219
|
+
#
|
220
|
+
# Options:
|
221
|
+
# from is sender identity
|
222
|
+
# tags list of tags that each agent in the result must match
|
223
|
+
class TagQuery < Packet
|
224
|
+
|
225
|
+
attr_accessor :from, :tags
|
226
|
+
|
227
|
+
def initialize(from, tags, size=nil)
|
228
|
+
@from = from
|
229
|
+
@tags = tags
|
230
|
+
@size = size
|
231
|
+
end
|
232
|
+
|
233
|
+
def self.json_create(o)
|
234
|
+
i = o['data']
|
235
|
+
new(i['from'], i['tags'], o['size'])
|
236
|
+
end
|
237
|
+
|
238
|
+
def to_s(filter=nil)
|
239
|
+
"#{super} <#{token}> #{type} from #{id_to_s(from)}, tags #{tags.inspect}"
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
218
243
|
# packet that means a work result notification sent from actor to mapper
|
219
244
|
#
|
220
245
|
# from is sender identity
|
@@ -68,27 +68,13 @@ module Nanite
|
|
68
68
|
@redis.set_members("tg-#{nanite}")
|
69
69
|
end
|
70
70
|
|
71
|
-
# Retrieve all agents services
|
72
|
-
def all_services
|
73
|
-
log_redis_error do
|
74
|
-
@redis.set_members('naniteservices')
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
# Retrieve all agents tags
|
79
|
-
def all_tags
|
80
|
-
log_redis_error do
|
81
|
-
@redis.set_members('nanitetags')
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
71
|
# Retrieve nanites implementing given service and exposing given tags
|
86
|
-
def
|
87
|
-
keys = tags
|
88
|
-
keys << service
|
89
|
-
|
90
|
-
|
91
|
-
|
72
|
+
def nanites_ids_for(request)
|
73
|
+
keys = request.tags ? request.tags.dup : []
|
74
|
+
keys << request.service if request.service
|
75
|
+
keys.compact!
|
76
|
+
return {} if keys.empty?
|
77
|
+
log_redis_error { @redis.set_intersect(keys) }
|
92
78
|
end
|
93
79
|
|
94
80
|
private
|
@@ -28,13 +28,14 @@ module Nanite
|
|
28
28
|
end
|
29
29
|
|
30
30
|
# Serialize message and sign it using X.509 certificate
|
31
|
-
def self.dump(obj)
|
31
|
+
def self.dump(obj, encrypt=nil)
|
32
32
|
raise "Missing certificate identity" unless @identity
|
33
33
|
raise "Missing certificate" unless @cert
|
34
34
|
raise "Missing certificate key" unless @key
|
35
35
|
raise "Missing certificate store" unless @store || !@encrypt
|
36
|
+
must_encrypt = encrypt.nil? ? @encrypt : encrypt
|
36
37
|
json = obj.to_json
|
37
|
-
if
|
38
|
+
if must_encrypt
|
38
39
|
certs = @store.get_recipients(obj)
|
39
40
|
json = EncryptedDocument.new(json, certs).encrypted_data if certs
|
40
41
|
end
|
@@ -51,9 +52,10 @@ module Nanite
|
|
51
52
|
data = JSON.load(json)
|
52
53
|
sig = Signature.from_data(data['signature'])
|
53
54
|
certs = @store.get_signer(data['id'])
|
55
|
+
raise "Failed to check signature for signer #{data['id']}" unless certs.any? { |c| sig.match?(c) }
|
54
56
|
raise "Could not find a cert for signer #{data['id']}" unless certs
|
55
57
|
certs = [ certs ] unless certs.respond_to?(:each)
|
56
|
-
jsn = data['data']
|
58
|
+
jsn = data['data']
|
57
59
|
if jsn && @encrypt && data['encrypted']
|
58
60
|
jsn = EncryptedDocument.from_data(jsn).decrypted_data(@key, @cert)
|
59
61
|
end
|
data/lib/nanite/state.rb
CHANGED
@@ -66,16 +66,6 @@ module Nanite
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
# Return all services exposed by all agents
|
70
|
-
def all_services
|
71
|
-
@tag_store.all_services
|
72
|
-
end
|
73
|
-
|
74
|
-
# Return all tags exposed by all agents
|
75
|
-
def all_tags
|
76
|
-
@tag_store.all_tags
|
77
|
-
end
|
78
|
-
|
79
69
|
# Update status and timestamp for given agent
|
80
70
|
def update_status(name, status)
|
81
71
|
log_redis_error do
|
@@ -111,11 +101,11 @@ module Nanite
|
|
111
101
|
|
112
102
|
# Return agents that implement given service and expose
|
113
103
|
# all given tags
|
114
|
-
def nanites_for(
|
115
|
-
res =
|
116
|
-
@tag_store.
|
104
|
+
def nanites_for(request)
|
105
|
+
res = {}
|
106
|
+
@tag_store.nanites_ids_for(request).each do |nanite_id|
|
117
107
|
if nanite = self[nanite_id]
|
118
|
-
res
|
108
|
+
res[nanite_id] = nanite
|
119
109
|
end
|
120
110
|
end
|
121
111
|
res
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rightscale-nanite-dev
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.1.
|
4
|
+
version: 0.4.1.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ezra Zygmuntowicz
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-30 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -39,7 +39,6 @@ files:
|
|
39
39
|
- README.rdoc
|
40
40
|
- Rakefile
|
41
41
|
- TODO
|
42
|
-
- lib/nanite
|
43
42
|
- lib/nanite/actor.rb
|
44
43
|
- lib/nanite/actor_registry.rb
|
45
44
|
- lib/nanite/admin.rb
|
@@ -52,7 +51,6 @@ files:
|
|
52
51
|
- lib/nanite/identity.rb
|
53
52
|
- lib/nanite/job.rb
|
54
53
|
- lib/nanite/local_state.rb
|
55
|
-
- lib/nanite/log
|
56
54
|
- lib/nanite/log/formatter.rb
|
57
55
|
- lib/nanite/log.rb
|
58
56
|
- lib/nanite/mapper.rb
|
@@ -62,7 +60,6 @@ files:
|
|
62
60
|
- lib/nanite/pid_file.rb
|
63
61
|
- lib/nanite/reaper.rb
|
64
62
|
- lib/nanite/redis_tag_store.rb
|
65
|
-
- lib/nanite/security
|
66
63
|
- lib/nanite/security/cached_certificate_store_proxy.rb
|
67
64
|
- lib/nanite/security/certificate.rb
|
68
65
|
- lib/nanite/security/certificate_cache.rb
|
@@ -83,6 +80,8 @@ files:
|
|
83
80
|
- bin/nanite-mapper
|
84
81
|
has_rdoc: true
|
85
82
|
homepage: http://github.com/ezmobius/nanite
|
83
|
+
licenses: []
|
84
|
+
|
86
85
|
post_install_message:
|
87
86
|
rdoc_options: []
|
88
87
|
|
@@ -103,9 +102,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
102
|
requirements: []
|
104
103
|
|
105
104
|
rubyforge_project:
|
106
|
-
rubygems_version: 1.3.
|
105
|
+
rubygems_version: 1.3.5
|
107
106
|
signing_key:
|
108
|
-
specification_version:
|
107
|
+
specification_version: 3
|
109
108
|
summary: self assembling fabric of ruby daemons
|
110
109
|
test_files: []
|
111
110
|
|