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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39d9ce50f924ae2ba75b9722feab0a00b40d7c18bca14fdfcfe823de5672ef4b
4
- data.tar.gz: 995a13165a99b8dde616ce02fc878876e9ede71b70016f3f08928312cd969566
3
+ metadata.gz: 427efea5fb0daf113212ee723e2e850ccb30723af7e7d5c6ea3576fe9e51979e
4
+ data.tar.gz: f6563c4ac916f06e66bba1d7ba6d69fed7818b601d9148d5d111dc7c6756d1d3
5
5
  SHA512:
6
- metadata.gz: 6f5eb468b00c381da6731f52295cce1636875ad4ba19df0494f2c8957e420cd4161599f65faccec22dd3e1238e1dacc2e18242ba4ecf216e5e3cb5686fe98c8a
7
- data.tar.gz: bf11c45c00a5a2d1f028ac028060588448a2dbc342c133bf0ab7526c8fe09585f17eb2624897231b4bc06b40199b6b6fa24c937ec43cf30e2b12a9eee933da1f
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
@@ -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; end
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 JSON
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 not the scheduler, run the payload.
45
+ # We have a master so we're a worker, run the payload.
46
46
  if peplum_options['master']
47
- execute( peplum_options, payload_options )
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
- def worker?
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
- # That's all we need to turn any application into a super version of itself.
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
- def payload
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 execute( peplum_options, payload_options )
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Peplum
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.2"
5
5
  end
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.0
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