workmesh 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/workmesh.rb +391 -0
- metadata +172 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 729804b3c48a7bdc88018de15bb49f297da200e310ebd306d2f4f75bb8832d3d
|
4
|
+
data.tar.gz: 4477a6b46a6e2ee01ba3576b722d5ffcde51b1128b7c916f1875e9b9f59e3305
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7306d782ff3a70b3e0e13f6436b9035e72e00b99d52103888d08713851af0685e06c31b62066c3f49b5452088498361632b1c0b6af6aa01a162f7cc90a5ba3ed
|
7
|
+
data.tar.gz: e9af5b428c21d0b6aa5ec5070a3a20121c54c4a9006893a1bef0e0a268efc7834b2ea8b78d5fa0e5e4c4d68ef3353727a8ea16fc3c2006ea39f4e4763fc9ba2e
|
data/lib/workmesh.rb
ADDED
@@ -0,0 +1,391 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
require 'sequel'
|
3
|
+
require 'blackstack-core'
|
4
|
+
require 'blackstack-nodes'
|
5
|
+
require 'blackstack-deployer'
|
6
|
+
require 'simple_command_line_parser'
|
7
|
+
require 'simple_cloud_logging'
|
8
|
+
|
9
|
+
require_relative '../deployment-routines/update-config'
|
10
|
+
require_relative '../deployment-routines/update-source'
|
11
|
+
|
12
|
+
=begin
|
13
|
+
# TODO: Move this to a gem with the CRDB module
|
14
|
+
#
|
15
|
+
# return a postgresql uuid
|
16
|
+
#
|
17
|
+
def guid()
|
18
|
+
DB['SELECT gen_random_uuid() AS id'].first[:id]
|
19
|
+
end
|
20
|
+
=end
|
21
|
+
|
22
|
+
# TODO: Move new() to a gem with the CRDB module
|
23
|
+
#
|
24
|
+
# return current datetime with format `%Y-%m-%d %H:%M:%S %Z`, using the timezone of the database (`select current_setting('TIMEZONE')`)
|
25
|
+
# TODO: I am hardcoding the value of `tz` because for any reason `SELECT current_setting('TIMEZONE')` returns `UTC` instead of
|
26
|
+
# `America/Argentina/Buenos_Aires` when I run it from Ruby. Be sure your database is ALWAYS configured with the correct timezone.
|
27
|
+
#
|
28
|
+
def now()
|
29
|
+
tz = 'America/Argentina/Buenos_Aires' #DB["SELECT current_setting('TIMEZONE') AS tz"].first[:tz]
|
30
|
+
DB["SELECT current_timestamp() at TIME ZONE '#{tz}' AS now"].first[:now]
|
31
|
+
end
|
32
|
+
|
33
|
+
module BlackStack
|
34
|
+
module Workmesh
|
35
|
+
# stub node class
|
36
|
+
# stub node class is already defined in the blackstack-nodes gem: https://github.com/leandrosardi/blackstack-nodes
|
37
|
+
# we inherit from it to add some extra methods and attributes
|
38
|
+
class Node
|
39
|
+
# stub node class is already defined in the blackstack-nodes gem: https://github.com/leandrosardi/blackstack-nodes
|
40
|
+
# we inherit from it to add some extra methods and attributes
|
41
|
+
include BlackStack::Infrastructure::NodeModule
|
42
|
+
# array of workers belonging to this node
|
43
|
+
attr_accessor :workmesh_api_key
|
44
|
+
attr_accessor :workmesh_port
|
45
|
+
attr_accessor :workmesh_service
|
46
|
+
# add validations to the node descriptor
|
47
|
+
def self.descriptor_errors(h)
|
48
|
+
errors = BlackStack::Infrastructure::NodeModule.descriptor_errors(h)
|
49
|
+
# validate: the key :max_workers exists and is an integer
|
50
|
+
errors << "The key :workmesh_api_key is missing" if h[:workmesh_api_key].nil?
|
51
|
+
errors << "The key :workmesh_api_key must be an String" unless h[:workmesh_api_key].is_a?(String)
|
52
|
+
# validate: the key :workmesh_port exists and is an integer
|
53
|
+
errors << "The key :workmesh_port is missing" if h[:workmesh_port].nil?
|
54
|
+
errors << "The key :workmesh_port must be an Integer" unless h[:workmesh_port].is_a?(Integer)
|
55
|
+
# validate: the key :workmesh_service exists and is an symbol, and its string matches with the name of one of the services in the @@services array
|
56
|
+
errors << "The key :workmesh_service is missing" if h[:workmesh_service].nil?
|
57
|
+
errors << "The key :workmesh_service must be an Symbol" unless h[:workmesh_service].is_a?(Symbol)
|
58
|
+
errors << "The key :workmesh_service must be one of the following: #{BlackStack::Workmesh.services.map { |s| s.name }}" unless BlackStack::Workmesh.services.map { |s| s.name }.include?(h[:workmesh_service].to_s)
|
59
|
+
# return list of errors
|
60
|
+
errors.uniq
|
61
|
+
end
|
62
|
+
# initialize the node
|
63
|
+
def initialize(h, i_logger=nil)
|
64
|
+
errors = BlackStack::Workmesh::Node.descriptor_errors(h)
|
65
|
+
raise "The node descriptor is not valid: #{errors.uniq.join(".\n")}" if errors.length > 0
|
66
|
+
super(h, i_logger)
|
67
|
+
self.workmesh_api_key = h[:workmesh_api_key]
|
68
|
+
self.workmesh_port = h[:workmesh_port]
|
69
|
+
self.workmesh_service = h[:workmesh_service]
|
70
|
+
end # def self.create(h)
|
71
|
+
# returh a hash descriptor of the node
|
72
|
+
def to_hash()
|
73
|
+
ret = super()
|
74
|
+
ret[:workmesh_api_key] = self.workmesh_api_key
|
75
|
+
ret[:workmesh_port] = self.workmesh_port
|
76
|
+
ret[:workmesh_service] = self.workmesh_service
|
77
|
+
ret
|
78
|
+
end
|
79
|
+
# run deployment routines
|
80
|
+
def deploy(l=nil)
|
81
|
+
l = BlackStack::DummyLogger.new(nil) if l.nil?
|
82
|
+
|
83
|
+
l.logs 'Updating config.rb... '
|
84
|
+
BlackStack::Deployer::run_routine(self.name, 'workmesh-update-config')
|
85
|
+
l.done
|
86
|
+
|
87
|
+
l.logs 'Updating source... '
|
88
|
+
BlackStack::Deployer::run_routine(self.name, 'workmesh-update-source')
|
89
|
+
l.done
|
90
|
+
end
|
91
|
+
end # class Node
|
92
|
+
|
93
|
+
class Protocol
|
94
|
+
attr_accessor :name
|
95
|
+
attr_accessor :entity_table, :entity_field_id, :entity_field_sort
|
96
|
+
attr_accessor :push_function, :entity_field_push_time, :entity_field_push_success, :entity_field_push_error_description
|
97
|
+
attr_accessor :pull_status_access_point
|
98
|
+
attr_accessor :pull_function, :enttity_field_pull_time, :entity_field_pull_success, :entity_field_pull_error_description
|
99
|
+
|
100
|
+
def self.descriptor_errors(h)
|
101
|
+
errors = []
|
102
|
+
# validate: the key :name exists and is a string
|
103
|
+
errors << "The key :name is missing" if h[:name].nil?
|
104
|
+
errors << "The key :name must be an String" unless h[:name].is_a?(String)
|
105
|
+
# validate: the key :entity_table exists and is an symbol
|
106
|
+
errors << "The key :entity_table is missing" if h[:entity_table].nil?
|
107
|
+
errors << "The key :entity_table must be an Symbol" unless h[:entity_table].is_a?(Symbol)
|
108
|
+
# validate: the key :entity_field_id exists and is an symbol
|
109
|
+
errors << "The key :entity_field_id is missing" if h[:entity_field_id].nil?
|
110
|
+
errors << "The key :entity_field_id must be an Symbol" unless h[:entity_field_id].is_a?(Symbol)
|
111
|
+
# validate: the key :entity_field_sort exists and is an symbol
|
112
|
+
errors << "The key :entity_field_sort is missing" if h[:entity_field_sort].nil?
|
113
|
+
errors << "The key :entity_field_sort must be an Symbol" unless h[:entity_field_sort].is_a?(Symbol)
|
114
|
+
|
115
|
+
# validate: the key :push_function is null or it is a procedure
|
116
|
+
#errors << "The key :push_function must be an Symbol" unless h[:push_function].nil? || h[:push_function].is_a?()
|
117
|
+
# validate: if :push_function exists, the key :entity_field_push_time exists and it is a symbol
|
118
|
+
errors << "The key :entity_field_push_time is missing" if h[:push_function] && h[:entity_field_push_time].nil?
|
119
|
+
# validate: if :push_function exists, the key :entity_field_push_success exists and it is a symbol
|
120
|
+
errors << "The key :entity_field_push_success is missing" if h[:push_function] && h[:entity_field_push_success].nil?
|
121
|
+
# validate: if :push_function exists, the key :entity_field_push_error_description exists and it is a symbol
|
122
|
+
errors << "The key :entity_field_push_error_description is missing" if h[:push_function] && h[:entity_field_push_error_description].nil?
|
123
|
+
|
124
|
+
# valiudate: if :pull_function exists, the key :pull_status_access_point exists and it is a string
|
125
|
+
errors << "The key :pull_status_access_point is missing" if h[:pull_function] && h[:pull_status_access_point].nil?
|
126
|
+
errors << "The key :pull_status_access_point must be an String" unless h[:pull_function].nil? || h[:pull_status_access_point].is_a?(String)
|
127
|
+
# validate: if :pull_function exists, the key :entity_field_pull_time exists and it is a symbol
|
128
|
+
errors << "The key :entity_field_pull_time is missing" if h[:pull_function] && h[:entity_field_pull_time].nil?
|
129
|
+
# validate: if :pull_function exists, the key :entity_field_pull_success exists and it is a symbol
|
130
|
+
errors << "The key :entity_field_pull_success is missing" if h[:pull_function] && h[:entity_field_pull_success].nil?
|
131
|
+
# validate: if :pull_function exists, the key :entity_field_pull_error_description exists and it is a symbol
|
132
|
+
errors << "The key :entity_field_pull_error_description is missing" if h[:pull_function] && h[:entity_field_pull_error_description].nil?
|
133
|
+
|
134
|
+
# return list of errors
|
135
|
+
errors.uniq
|
136
|
+
end
|
137
|
+
|
138
|
+
def initialize(h)
|
139
|
+
errors = BlackStack::Workmesh::Protocol.descriptor_errors(h)
|
140
|
+
raise "The protocol descriptor is not valid: #{errors.uniq.join(".\n")}" if errors.length > 0
|
141
|
+
self.name = h[:name]
|
142
|
+
self.entity_table = h[:entity_table]
|
143
|
+
self.entity_field_id = h[:entity_field_id]
|
144
|
+
self.entity_field_sort = h[:entity_field_sort]
|
145
|
+
self.push_function = h[:push_function]
|
146
|
+
self.entity_field_push_time = h[:entity_field_push_time]
|
147
|
+
self.entity_field_push_success = h[:entity_field_push_success]
|
148
|
+
self.entity_field_push_error_description = h[:entity_field_push_error_description]
|
149
|
+
self.pull_function = h[:pull_function]
|
150
|
+
self.enttity_field_pull_time = h[:entity_field_pull_time]
|
151
|
+
self.entity_field_pull_success = h[:entity_field_pull_success]
|
152
|
+
self.entity_field_pull_error_description = h[:entity_field_pull_error_description]
|
153
|
+
end
|
154
|
+
|
155
|
+
def to_hash()
|
156
|
+
ret = super()
|
157
|
+
ret[:name] = self.name
|
158
|
+
ret[:entity_table] = self.entity_table
|
159
|
+
ret[:entity_field_id] = self.entity_field_id
|
160
|
+
ret[:entity_field_sort] = self.entity_field_sort
|
161
|
+
ret[:push_function] = self.push_function
|
162
|
+
ret[:entity_field_push_time] = self.entity_field_push_time
|
163
|
+
ret[:entity_field_push_success] = self.entity_field_push_success
|
164
|
+
ret[:entity_field_push_error_description] = self.entity_field_push_error_description
|
165
|
+
ret[:pull_function] = self.pull_function
|
166
|
+
ret[:enttity_field_pull_time] = self.enttity_field_pull_time
|
167
|
+
ret[:entity_field_pull_success] = self.entity_field_pull_success
|
168
|
+
ret[:entity_field_pull_error_description] = self.entity_field_pull_error_description
|
169
|
+
ret
|
170
|
+
end
|
171
|
+
|
172
|
+
# execute the push function of this protocol, and update the push flags
|
173
|
+
def push(entity, node)
|
174
|
+
raise 'The push function is not defined' if self.push_function.nil?
|
175
|
+
entity[entity_field_push_time] = now()
|
176
|
+
begin
|
177
|
+
self.push_function.call(entity, node)
|
178
|
+
entity[entity_field_push_success] = true
|
179
|
+
entity[entity_field_push_error_description] = nil
|
180
|
+
entity.save
|
181
|
+
rescue => e
|
182
|
+
entity[entity_field_push_success] = false
|
183
|
+
entity[entity_field_push_error_description] = e.message
|
184
|
+
entity.save
|
185
|
+
raise e
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end # class Protocol
|
189
|
+
|
190
|
+
# stub worker class
|
191
|
+
class Service
|
192
|
+
ASSIGANTIONS = [:entityweight, :roundrobin, :entitynumber]
|
193
|
+
# name to identify uniquely the worker
|
194
|
+
attr_accessor :name, :entity_table, :entity_field_assignation, :protocols, :assignation
|
195
|
+
# return an array with the errors found in the description of the job
|
196
|
+
def self.descriptor_errors(h)
|
197
|
+
errors = []
|
198
|
+
# validate: the key :name exists and is an string
|
199
|
+
errors << "The key :name is missing" if h[:name].nil?
|
200
|
+
errors << "The key :name must be an String" unless h[:name].is_a?(String)
|
201
|
+
# validate: the key :entity_table exists and is an symbol
|
202
|
+
errors << "The key :entity_table is missing" if h[:entity_table].nil?
|
203
|
+
errors << "The key :entity_table must be an Symbol" unless h[:entity_table].is_a?(Symbol)
|
204
|
+
# validate: the key :entity_field_assignation exists and is an symbol
|
205
|
+
errors << "The key :entity_field_assignation is missing" if h[:entity_field_assignation].nil?
|
206
|
+
errors << "The key :entity_field_assignation must be an Symbol" unless h[:entity_field_assignation].is_a?(Symbol)
|
207
|
+
# validate: the key :protocols exists is nil or it is an array of valid hash descritors of the Protocol class.
|
208
|
+
errors << "The key :protocols must be an Array" unless h[:protocols].nil? || h[:protocols].is_a?(Array)
|
209
|
+
if h[:protocols].is_a?(Array)
|
210
|
+
h[:protocols].each do |protocol|
|
211
|
+
errors << "The key :protocols must be an Array of valid hash descritors of the Protocol class" unless protocol.is_a?(Hash)
|
212
|
+
errors << "The key :protocols must be an Array of valid hash descritors of the Protocol class" unless Protocol.descriptor_errors(protocol).length == 0
|
213
|
+
end
|
214
|
+
end
|
215
|
+
# validate: the key :assignation is nil or it is a symbol belonging the array ASSIGANTIONS
|
216
|
+
errors << "The key :assignation must be an Symbol" unless h[:assignation].nil? || h[:assignation].is_a?(Symbol)
|
217
|
+
unless h[:assignation].nil?
|
218
|
+
errors << "The key :assignation must be one of the following values: #{ASSIGANTIONS.join(", ")}" unless ASSIGANTIONS.include?(h[:assignation])
|
219
|
+
end
|
220
|
+
# return list of errors
|
221
|
+
errors.uniq
|
222
|
+
end
|
223
|
+
# setup dispatcher configuration here
|
224
|
+
def initialize(h)
|
225
|
+
errors = BlackStack::Workmesh::Service.descriptor_errors(h)
|
226
|
+
raise "The worker descriptor is not valid: #{errors.uniq.join(".\n")}" if errors.length > 0
|
227
|
+
self.name = h[:name]
|
228
|
+
self.entity_table = h[:entity_table]
|
229
|
+
self.entity_field_assignation = h[:entity_field_assignation]
|
230
|
+
self.protocols = []
|
231
|
+
if h[:protocols]
|
232
|
+
h[:protocols].each do |i|
|
233
|
+
self.protocols << BlackStack::Workmesh::Protocol.new(i)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
self.assignation = h[:assignation]
|
237
|
+
end
|
238
|
+
# return a hash descriptor of the worker
|
239
|
+
def to_hash()
|
240
|
+
{
|
241
|
+
:name => self.name,
|
242
|
+
:entity_table => self.entity_table,
|
243
|
+
:entity_field_assignation => self.entity_field_assignation,
|
244
|
+
:protocols => self.protocols.map { |p| p.to_hash },
|
245
|
+
:assignation => self.assignation
|
246
|
+
}
|
247
|
+
end
|
248
|
+
# get a protocol from its name
|
249
|
+
def protocol(name)
|
250
|
+
self.protocols.select { |p| p.name.to_s == name.to_s }.first
|
251
|
+
end
|
252
|
+
end # class Service
|
253
|
+
|
254
|
+
# hash with the round-robin positions per service.
|
255
|
+
@@roundrobin = {}
|
256
|
+
|
257
|
+
# infrastructure configuration
|
258
|
+
@@nodes = []
|
259
|
+
@@services = []
|
260
|
+
|
261
|
+
# logger configuration
|
262
|
+
@@log_filename = nil
|
263
|
+
@@logger = BlackStack::DummyLogger.new(nil)
|
264
|
+
|
265
|
+
# Connection string to the database. Example: mysql2://user:password@localhost:3306/database
|
266
|
+
@@connection_string = nil
|
267
|
+
|
268
|
+
# define a filename for the log file.
|
269
|
+
def self.set_log_filename(s)
|
270
|
+
@@log_filename = s
|
271
|
+
@@logger = BlackStack::LocalLogger.new(s)
|
272
|
+
end
|
273
|
+
|
274
|
+
# return the logger.
|
275
|
+
def self.logger()
|
276
|
+
@@logger
|
277
|
+
end
|
278
|
+
|
279
|
+
def self.set_logger(l)
|
280
|
+
@@logger = l
|
281
|
+
end
|
282
|
+
|
283
|
+
# return the log filename.
|
284
|
+
def self.log_filename()
|
285
|
+
@@log_filename
|
286
|
+
end
|
287
|
+
|
288
|
+
# define the connectionstring to the database.
|
289
|
+
def self.set_connection_string(s)
|
290
|
+
@@connection_string = s
|
291
|
+
end
|
292
|
+
|
293
|
+
# return connection string to the database. Example: mysql2://user:password@localhost:3306/database
|
294
|
+
def self.connection_string()
|
295
|
+
@@connection_string
|
296
|
+
end
|
297
|
+
|
298
|
+
# add_node
|
299
|
+
# add a node to the infrastructure
|
300
|
+
def self.add_node(h)
|
301
|
+
@@nodes << BlackStack::Workmesh::Node.new(h)
|
302
|
+
# add to deployer
|
303
|
+
BlackStack::Deployer.add_node(h) #if @@integrate_with_blackstack_deployer
|
304
|
+
end
|
305
|
+
|
306
|
+
def self.nodes
|
307
|
+
@@nodes
|
308
|
+
end
|
309
|
+
|
310
|
+
def self.node(name)
|
311
|
+
@@nodes.select { |n| n.name.to_s == name.to_s }.first
|
312
|
+
end
|
313
|
+
|
314
|
+
# add_service
|
315
|
+
# add a service to the infrastructure
|
316
|
+
def self.add_service(h)
|
317
|
+
@@services << BlackStack::Workmesh::Service.new(h)
|
318
|
+
end
|
319
|
+
|
320
|
+
def self.services
|
321
|
+
@@services
|
322
|
+
end
|
323
|
+
|
324
|
+
def self.service(name)
|
325
|
+
@@services.select { |s| s.name.to_s == name.to_s }.first
|
326
|
+
end
|
327
|
+
|
328
|
+
# assign object to a node using a round-robin algorithm
|
329
|
+
# this method is used when the service assignation is :roundrobin
|
330
|
+
# this method is for internal use only, and it should not be called directly.
|
331
|
+
def self.roundrobin(o, service_name)
|
332
|
+
@@roundrobin[service_name] = 0 if @@roundrobin[service_name].nil?
|
333
|
+
# getting the service
|
334
|
+
s = @@services.select { |s| s.name.to_s == service_name.to_s }.first
|
335
|
+
# getting all the nodes assigned to the service
|
336
|
+
nodes = @@nodes.select { |n| n.workmesh_service.to_s == service_name.to_s }.sort_by { |n| n.name.to_s }
|
337
|
+
# increase i
|
338
|
+
@@roundrobin[service_name] += 1
|
339
|
+
@@roundrobin[service_name] = 0 if @@roundrobin[service_name] >= nodes.length
|
340
|
+
# assign the object to the node
|
341
|
+
n = nodes[@@roundrobin[service_name]]
|
342
|
+
o[s.entity_field_assignation] = n.name
|
343
|
+
o.save
|
344
|
+
# return
|
345
|
+
n
|
346
|
+
end
|
347
|
+
|
348
|
+
# return the assigned node to an object, for a specific service.
|
349
|
+
# if the object has not a node assigned, then return nil.
|
350
|
+
def self.assigned_node(o, service_name)
|
351
|
+
# getting the service
|
352
|
+
s = @@services.select { |s| s.name.to_s == service_name.to_s }.first
|
353
|
+
# validate: the service exists
|
354
|
+
raise "The service #{service_name} does not exists" if s.nil?
|
355
|
+
# validate: the object o is an instance of the Sequel Class mapping the table :entity_table
|
356
|
+
raise "The object o is not an instance of :entity_table (#{s.entity_table.to_s})" unless o.is_a?(Sequel::Model) && o.class.table_name.to_s == s.entity_table.to_s
|
357
|
+
# if the object has not a node assigned, then return nil.
|
358
|
+
return nil if o[s.entity_field_assignation].nil?
|
359
|
+
# return the node
|
360
|
+
@@nodes.select { |n| n.name.to_s == o[s.entity_field_assignation].to_s }.first
|
361
|
+
end
|
362
|
+
|
363
|
+
# assign object to a node
|
364
|
+
def self.assign(o, service_name, h = {})
|
365
|
+
# getting the service
|
366
|
+
s = @@services.select { |s| s.name.to_s == service_name.to_s }.first
|
367
|
+
# validate: the service exists
|
368
|
+
raise "The service #{service_name} does not exists" if s.nil?
|
369
|
+
# validate: the object o is an instance of the Sequel Class mapping the table :entity_table
|
370
|
+
raise "The object o is not an instance of :entity_table (#{s.entity_table.to_s})" unless o.is_a?(Sequel::Model) && o.class.table_name.to_s == s.entity_table.to_s
|
371
|
+
# reassign
|
372
|
+
if h[:reassign] == true
|
373
|
+
o[s.entity_field_assignation] = nil
|
374
|
+
o.save
|
375
|
+
end
|
376
|
+
# validate: the object o has not been assigned yet
|
377
|
+
raise "The object o has been already assigned to a node. Use the :reassign parameter for reassignation." unless o[s.entity_field_assignation].nil?
|
378
|
+
# decide the assignation method
|
379
|
+
if s.assignation == :entityweight
|
380
|
+
raise 'The assignation method :entityweight is not implemented yet.'
|
381
|
+
elsif s.assignation == :roundrobin
|
382
|
+
return BlackStack::Workmesh.roundrobin(o, service_name)
|
383
|
+
elsif s.assignation == :entitynumber
|
384
|
+
raise 'The assignation method :entitynumber is not implemented yet.'
|
385
|
+
else
|
386
|
+
raise "The assignation method #{s.assignation} is unknown."
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
end # module Workmesh
|
391
|
+
end # module BlackStack
|
metadata
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: workmesh
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Leandro Daniel Sardi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-06-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: sequel
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.56.0
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 5.56.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 5.56.0
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 5.56.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: blackstack-core
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 1.2.3
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 1.2.3
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 1.2.3
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 1.2.3
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: blackstack-nodes
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 1.2.11
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.2.11
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.2.11
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.2.11
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: blackstack-deployer
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 1.2.24
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.2.24
|
83
|
+
type: :runtime
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.2.24
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 1.2.24
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: simple_command_line_parser
|
95
|
+
requirement: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - "~>"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 1.1.2
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 1.1.2
|
103
|
+
type: :runtime
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.1.2
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 1.1.2
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: simple_cloud_logging
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - "~>"
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: 1.2.2
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 1.2.2
|
123
|
+
type: :runtime
|
124
|
+
prerelease: false
|
125
|
+
version_requirements: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - "~>"
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: 1.2.2
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 1.2.2
|
133
|
+
description: "WorkMesh is an open-source micro-services orchestration system for automatng
|
134
|
+
software scaling and work distribution.\n\n Some hints:\n \n - In the **WorkMesh**
|
135
|
+
world, a **micro-service** is an **external web-service** who receives tasks for
|
136
|
+
any kind of offline processing, and returns the result to **master**. Just that.
|
137
|
+
Nothing more.\n \n - This library is for defininng the micro-service protocol
|
138
|
+
at the **master** side.\n \n - For creating your own micro-service, refer to [micro.template](https://github.com/leandrosardi/micro.template)
|
139
|
+
project.\n \n - If you are looking for a multi-threading processing framework,
|
140
|
+
you should refer to [Pampa](https://github.com/leandrosardi/pampa) instead.\n \nFind
|
141
|
+
documentation here: https://github.com/leandrosardi/workmesh\n"
|
142
|
+
email: leandro.sardi@expandedventure.com
|
143
|
+
executables: []
|
144
|
+
extensions: []
|
145
|
+
extra_rdoc_files: []
|
146
|
+
files:
|
147
|
+
- lib/workmesh.rb
|
148
|
+
homepage: https://rubygems.org/gems/workmesh
|
149
|
+
licenses:
|
150
|
+
- MIT
|
151
|
+
metadata: {}
|
152
|
+
post_install_message:
|
153
|
+
rdoc_options: []
|
154
|
+
require_paths:
|
155
|
+
- lib
|
156
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
requirements: []
|
167
|
+
rubygems_version: 3.3.7
|
168
|
+
signing_key:
|
169
|
+
specification_version: 4
|
170
|
+
summary: WorkMesh is an open-source micro-services orchestration system for automatng
|
171
|
+
software scaling and work distribution.
|
172
|
+
test_files: []
|