peplum 0.3.0 → 0.3.2
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/lib/peplum/application/payload.rb +67 -0
- data/lib/peplum/application/worker.rb +19 -0
- data/lib/peplum/application.rb +48 -32
- data/lib/peplum/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 427efea5fb0daf113212ee723e2e850ccb30723af7e7d5c6ea3576fe9e51979e
|
4
|
+
data.tar.gz: f6563c4ac916f06e66bba1d7ba6d69fed7818b601d9148d5d111dc7c6756d1d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ecb729393728b371af870f5615a00e6d815e773932aefedce3aefa4e07e20f82eb2dbd0bee40e99add29f2a1b915654115c74df3cfb11427f87507cc4d85e584
|
7
|
+
data.tar.gz: 5d8ea07c8ccbac15dc63116d377b4259662634f75b105b77223b6805ded8e5176e0bbc292d67cc1a9d7768929e7c3045d16925c7b1e239c884dcb10bdead0664
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'peplum/core_ext/array'
|
2
|
+
|
3
|
+
module Peplum
|
4
|
+
class Application
|
5
|
+
module Payload
|
6
|
+
|
7
|
+
class Error < Error
|
8
|
+
class ImplementationMissing < Error
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Run payload against `objects` based on given `options`
|
13
|
+
#
|
14
|
+
# @param [Array] objects Objects that this worker should process.
|
15
|
+
# @param [Hash, NilClass] options Worker options.
|
16
|
+
# @abstract
|
17
|
+
def run( objects, options )
|
18
|
+
fail Error::ImplementationMissing, 'Missing implementation.'
|
19
|
+
end
|
20
|
+
|
21
|
+
# Distribute `objects` into `groups_of` amount of groups, one for each worker.
|
22
|
+
#
|
23
|
+
# @param [Array] objects All objects that need to be processed.
|
24
|
+
# @param [Integer] groups_of Amount of object groups that should be generated.
|
25
|
+
#
|
26
|
+
# @return [Array<Array<Object>>] `objects` split in `chunks` amount of groups.
|
27
|
+
def split( objects, groups_of )
|
28
|
+
objects.chunk groups_of
|
29
|
+
end
|
30
|
+
|
31
|
+
# Merge result `data` for reporting.
|
32
|
+
#
|
33
|
+
# By default provides a generic implementation that merges the values of `Hash`es and `Array`s.
|
34
|
+
# If `String`s or `Numeric`s are contained, the Array is returned as is.
|
35
|
+
#
|
36
|
+
# @param [Array] data Report data from workers.
|
37
|
+
# @return [Object] Merged results.
|
38
|
+
#
|
39
|
+
# @raise [Error::ImplementationMissing] When the data cannot be handled.
|
40
|
+
def merge( data )
|
41
|
+
case data.first
|
42
|
+
when Hash
|
43
|
+
f = data.pop
|
44
|
+
data.each do |d|
|
45
|
+
|
46
|
+
if !f.is_a? Hash
|
47
|
+
fail Error::ImplementationMissing, 'Missing implementation: Item not a Hash!'
|
48
|
+
end
|
49
|
+
|
50
|
+
f.merge! d
|
51
|
+
end
|
52
|
+
f
|
53
|
+
|
54
|
+
when Array
|
55
|
+
data.flatten
|
56
|
+
|
57
|
+
when String, Numeric
|
58
|
+
data
|
59
|
+
|
60
|
+
else
|
61
|
+
fail Error::ImplementationMissing, 'Missing implementation.'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Peplum
|
2
|
+
class Application
|
3
|
+
|
4
|
+
module Worker
|
5
|
+
|
6
|
+
# @return [Cuboid::RPC::Server::Instance::Peers]
|
7
|
+
attr_reader :peers
|
8
|
+
|
9
|
+
# @return [Cuboid::RPC::Client::Instance, NilClass]
|
10
|
+
attr_reader :scheduler
|
11
|
+
|
12
|
+
def peers
|
13
|
+
@peers ||= Cuboid::RPC::Server::Instance::Peers.new
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
data/lib/peplum/application.rb
CHANGED
@@ -1,88 +1,93 @@
|
|
1
1
|
require 'cuboid'
|
2
2
|
require 'json'
|
3
3
|
require 'peplum'
|
4
|
-
require 'peplum/core_ext/array'
|
5
4
|
|
6
5
|
module Peplum
|
7
6
|
class Application < Cuboid::Application
|
7
|
+
require 'peplum/application/worker'
|
8
|
+
require 'peplum/application/payload'
|
9
|
+
|
8
10
|
require 'peplum/application/services/shared_hash'
|
9
11
|
require 'peplum/application/services/scheduler'
|
10
12
|
|
11
|
-
class Error < Peplum::Error
|
13
|
+
class Error < Peplum::Error
|
14
|
+
class PayloadMissing < Error
|
15
|
+
end
|
16
|
+
end
|
12
17
|
|
18
|
+
# Hijack Cuboid to set ourselves up.
|
13
19
|
class <<self
|
14
20
|
def inherited( application )
|
15
21
|
super
|
16
22
|
|
23
|
+
# Don't trust Cuboid's auto-detection for this, make sure the inheriting class is the Cuboid application.
|
17
24
|
Cuboid::Application.application = application
|
18
25
|
|
19
26
|
application.validate_options_with :validate_options
|
20
|
-
application.serialize_with
|
27
|
+
application.serialize_with MessagePack
|
21
28
|
|
22
29
|
application.instance_service_for :scheduler, Services::Scheduler
|
30
|
+
|
31
|
+
# Shared, in-memory key-value store for the workers, the scheduler will not be participate.
|
23
32
|
application.instance_service_for :shared_hash, Services::SharedHash
|
24
33
|
end
|
25
34
|
end
|
26
35
|
|
27
|
-
attr_reader :peers
|
28
|
-
attr_reader :master
|
29
|
-
|
30
|
-
def initialize(*)
|
31
|
-
super
|
32
|
-
|
33
|
-
@peers = Cuboid::RPC::Server::Instance::Peers.new
|
34
|
-
end
|
35
|
-
|
36
36
|
def run
|
37
|
-
Raktr.global.on_error do |_, e|
|
38
|
-
$stderr.puts e
|
39
|
-
end
|
40
|
-
|
41
37
|
options = @options.dup
|
38
|
+
|
39
|
+
# System options.
|
42
40
|
peplum_options = options.delete( 'peplum' )
|
41
|
+
|
42
|
+
# Payload options.
|
43
43
|
payload_options = options.delete( 'payload' )
|
44
44
|
|
45
|
-
# We have a master so we're
|
45
|
+
# We have a master so we're a worker, run the payload.
|
46
46
|
if peplum_options['master']
|
47
|
-
|
47
|
+
work( peplum_options, payload_options )
|
48
48
|
|
49
|
-
# We're the scheduler Instance, get to grouping and spawning.
|
49
|
+
# We're the scheduler Instance, get to grouping objects and spawning workers.
|
50
50
|
else
|
51
51
|
schedule( peplum_options, payload_options )
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
|
56
|
-
# Has a master?
|
57
|
-
!!@master
|
58
|
-
end
|
59
|
-
|
60
|
-
# Implements:
|
61
|
-
# * `.run` -- Worker; executes its payload against `objects`.
|
62
|
-
# * `.split` -- Splits given `objects` into groups for each worker.
|
63
|
-
# * `.merge` -- Merges results from multiple workers.
|
55
|
+
# @return [#run, #split, #merge]
|
64
56
|
#
|
65
|
-
#
|
57
|
+
# * `#run` -- Worker; executes its payload against `objects`.
|
58
|
+
# * `#split` -- Scheduler; splits given `objects` into groups for each worker.
|
59
|
+
# * `#merge` -- Scheduler; merges results from multiple workers.
|
60
|
+
#
|
61
|
+
# That's all we need to turn any application into a super version of itself.
|
66
62
|
#
|
67
63
|
# @abstract
|
68
|
-
|
69
|
-
fail Error, 'Missing #payload!'
|
64
|
+
def payload
|
65
|
+
fail Error::PayloadMissing, 'Missing #payload implementation!'
|
70
66
|
end
|
71
67
|
|
68
|
+
# Overload {Cuboid#report} and delegate to the {Payload.merge} prior passing it on to {Cuboid}.
|
69
|
+
# @private
|
72
70
|
def report( data )
|
73
71
|
super payload.merge( data )
|
74
72
|
end
|
75
73
|
|
76
74
|
private
|
77
75
|
|
78
|
-
def
|
76
|
+
def work( peplum_options, payload_options )
|
77
|
+
# We're now a worker class!
|
78
|
+
self.class.include Worker
|
79
|
+
|
79
80
|
master_info = peplum_options.delete( 'master' )
|
80
81
|
@master = Processes::Instances.connect( master_info['url'], master_info['token'] )
|
81
82
|
|
83
|
+
# Configure us to know the rest of our worker peers.
|
84
|
+
# Required for the SharedHash service.
|
82
85
|
self.peers.set( peplum_options.delete( 'peers' ) || {} )
|
83
86
|
|
87
|
+
# Deliver the payload.
|
84
88
|
report_data = payload.run( peplum_options['objects'], payload_options )
|
85
89
|
|
90
|
+
# Signal that we're done by passing our report to the scheduler.
|
86
91
|
@master.scheduler.report report_data, Cuboid::Options.rpc.url
|
87
92
|
end
|
88
93
|
|
@@ -151,9 +156,20 @@ module Peplum
|
|
151
156
|
fail Error, 'Options: Missing :max_workers'
|
152
157
|
end
|
153
158
|
|
159
|
+
validate_payload
|
160
|
+
|
154
161
|
@options = options
|
155
162
|
true
|
156
163
|
end
|
157
164
|
|
165
|
+
def validate_payload
|
166
|
+
p = self.payload
|
167
|
+
|
168
|
+
%w(run merge split).each do |m|
|
169
|
+
next if p.respond_to? m
|
170
|
+
fail Payload::Error::ImplementationMissing, "#{payload} missing implementation for: ##{m}"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
158
174
|
end
|
159
175
|
end
|
data/lib/peplum/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: peplum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tasos Laskos
|
@@ -34,8 +34,10 @@ files:
|
|
34
34
|
- bin/.gitkeep
|
35
35
|
- lib/peplum.rb
|
36
36
|
- lib/peplum/application.rb
|
37
|
+
- lib/peplum/application/payload.rb
|
37
38
|
- lib/peplum/application/services/scheduler.rb
|
38
39
|
- lib/peplum/application/services/shared_hash.rb
|
40
|
+
- lib/peplum/application/worker.rb
|
39
41
|
- lib/peplum/core_ext/array.rb
|
40
42
|
- lib/peplum/version.rb
|
41
43
|
- peplum.gemspec
|