low_event 0.3.1 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52951b7a6e2b9553ac992c304630c0754e5e812c1bda2d90d80e6c23c3f25efe
4
- data.tar.gz: 5af40c08e8c34a264b3459bc404aa0e4da972449b4000eb92e59272e8c9684b4
3
+ metadata.gz: c63adedbf6028a0a6c3e15620d5ea736ba53961d318b22ab44d6bc5d75b853b3
4
+ data.tar.gz: 7956e7c903e68097c74d5eb41a706b8948ed0b98dea333748b3caec15786e890
5
5
  SHA512:
6
- metadata.gz: 0b4ef4e0f8b5f8cb435ef3185b7ccc14c468625ac7bee5ba6f3c4009778bbef6f5af1ce020210aed8f34770998c0588cbd8a5c3a496761d4653870e7ec3c917a
7
- data.tar.gz: dd046cf53a1d39449e9990d899788ce618de3262d75b05dae8fb5d9957d9eab0ad9a8bafc036778a963d989c11f244ddf5a94210aecc4e8ca2387aa9903c89f5
6
+ metadata.gz: 9c801ef8056b37fea3559da0c9f2729b3c955bf08fd7b430691ea66504a98061d890754d6d1eff7be2173e4ee1a83913eec151902ca2bce4f64da11b6da8e3a4
7
+ data.tar.gz: 7c801efafc85f09105f91fc3961988304b6c3646f01a30d45cceed0236bf5e20750f91d03cae4958d209a90269f254800d21bbfe55170f3bfe03a419ea32334b
data/lib/events/event.rb CHANGED
@@ -1,26 +1,63 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'observers'
4
+ require_relative '../support/value_object'
5
+
3
6
  module Low
7
+ # An event represents what is currently happening in your application.
8
+ #
9
+ # Events are mutable in most cases (except for RenderEvent). They are action-driven, representing inputs and outputs
10
+ # that are currently happening in a linear pipeline-like flow. They are present-tense and one-to-many with one return value.
11
+ # The result of the previous event is made available to the next event. [UNRELEASED]
12
+ #
13
+ # Integrations:
14
+ # - Observers for observer pattern via an event-centric API
15
+ # - EventPool for a tree of events and their child events
16
+ # - LowState for state machines to trigger multiple actions [UNLRELEASED]
4
17
  class Event
5
18
  include LowType
19
+ include Support::ValueObject
6
20
 
7
- attr_reader :action
21
+ attr_reader :key, :action, :created_at
22
+ attr_accessor :children
8
23
 
9
- def initialize(action: nil)
24
+ def initialize(key:, action: nil, children: [])
25
+ @key = key
10
26
  @action = action
27
+ @children = children
28
+ @created_at = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
29
+ end
30
+
31
+ def trigger
32
+ event_tree = branch
33
+ key = Observers[@key]
34
+ key.trigger(event: self) { restore_level(event_tree:) }
11
35
  end
12
36
 
13
- # Consider LowEvent a value object.
14
- def ==(other) = other.class == self.class
15
- def eql?(other) = self == other
16
- def hash = [self.class].hash
37
+ def take
38
+ event_tree = branch
39
+ key = Observers[@key]
40
+ key.take(event: self) { restore_level(event_tree:) }
41
+ end
42
+
43
+ private
44
+
45
+ def branch
46
+ event_tree = Providers['low.event.pool'].current_event_tree(event: self)
47
+ event_tree.branch(event: self)
48
+ end
49
+
50
+ def restore_level(event_tree:)
51
+ event_tree.current_event = self if event_tree.respond_to?(:current_event)
52
+ end
17
53
 
18
- # Integrate with Observers, providing a self-contained API via an event's class.
19
54
  class << self
20
55
  def trigger(**kwargs)
21
- observable = Observers::Observables[self] || raise(Observers::Observables::MissingKeyError)
22
- event = new(**kwargs)
23
- observable.trigger action: event.action, event:
56
+ new(**kwargs).trigger
57
+ end
58
+
59
+ def take(**kwargs)
60
+ new(**kwargs).take
24
61
  end
25
62
 
26
63
  def inherited(child)
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'low_type'
4
+
5
+ module Low
6
+ module Events
7
+ # An event that happens on event tree branching and isn't added to the event tree/sequence.
8
+ class HiddenEvent
9
+ include LowType
10
+
11
+ attr_reader :key, :action, :created_at
12
+
13
+ def initialize(key:, action: nil)
14
+ @key = key
15
+ @action = action
16
+ @created_at = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
17
+ end
18
+
19
+ def trigger
20
+ event_tree = branch
21
+ key = Observers[@key]
22
+ key.trigger(event: self) { restore_level(event_tree:) }
23
+ end
24
+
25
+ class << self
26
+ def trigger(**kwargs)
27
+ new(**kwargs).trigger
28
+ end
29
+
30
+ def inherited(child)
31
+ child.include LowType
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -8,7 +8,7 @@ module Low
8
8
  attr_reader :request
9
9
 
10
10
  def initialize(request:, action: :handle)
11
- super(action:)
11
+ super(key: self.class, action:)
12
12
 
13
13
  @request = request
14
14
  end
@@ -7,8 +7,8 @@ module Low
7
7
  class StatusEvent < Event
8
8
  attr_reader :status, :request
9
9
 
10
- def initialize(status:, request:)
11
- super()
10
+ def initialize(status:, request:, action: :render)
11
+ super(key: status, action:)
12
12
 
13
13
  @status = status
14
14
  @request = request
data/lib/low_event.rb CHANGED
@@ -2,12 +2,18 @@
2
2
 
3
3
  require 'low_type'
4
4
  require 'observers'
5
+ require 'providers'
5
6
 
6
7
  require_relative 'events/event'
7
8
  require_relative 'events/render_event'
8
9
  require_relative 'events/request_event'
9
10
  require_relative 'events/response_event'
10
11
  require_relative 'events/status_event'
11
- require_relative 'factories/response_factory'
12
+ require_relative 'factories/response_factory' # TODO: Find out who's using this and require it there.
13
+ require_relative 'pool/event_pool'
14
+
15
+ Providers.define('low.event.pool') do
16
+ Low::Events::EventPool.new
17
+ end
12
18
 
13
19
  LowEvent = Low::Event
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../events/hidden_event'
4
+
5
+ module Low
6
+ module Events
7
+ class BranchEvent < HiddenEvent
8
+ attr_reader :event_tree, :event
9
+
10
+ def initialize(event_tree:, event:)
11
+ super(key: BranchEvent, action: :branch)
12
+
13
+ @event_tree = event_tree
14
+ @event = event
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'observers'
4
+
5
+ require_relative '../events/request_event'
6
+ require_relative 'event_tree'
7
+ require_relative '../support/pool_hash'
8
+
9
+ module Low
10
+ module Events
11
+ class EventPool
12
+ include Observers
13
+
14
+ BUFFER_SIZE = 100
15
+
16
+ def initialize
17
+ @pool = Support::PoolHash.new(BUFFER_SIZE)
18
+ @request_counts = Support::PoolHash.new(BUFFER_SIZE)
19
+ end
20
+
21
+ def current_event_tree(event:)
22
+ request_id = request_id(event:)
23
+
24
+ return @pool[request_id] if @pool[request_id]
25
+
26
+ event_tree = @pool.add(request_id, EventTree.new(request_id:))
27
+ trigger action: :new_event_tree, event: event_tree
28
+
29
+ event_tree
30
+ end
31
+
32
+ def event_trees
33
+ @pool
34
+ end
35
+
36
+ private
37
+
38
+ def request_id(event:)
39
+ fiber_id = Fiber.current.object_id
40
+ increment_request_counts(fiber_id:) if event.is_a?(RequestEvent)
41
+ "#{fiber_id}-#{@request_counts[fiber_id]}"
42
+ end
43
+
44
+ def increment_request_counts(fiber_id:)
45
+ @request_counts[fiber_id] ||= 0
46
+ @request_counts[fiber_id] += 1
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'observers'
4
+ require_relative 'branch_event'
5
+
6
+ module Low
7
+ module Events
8
+ class EventTree
9
+ include Observers
10
+
11
+ attr_reader :request_id, :root_event, :sequence
12
+ attr_accessor :current_event
13
+
14
+ def initialize(request_id: nil)
15
+ @request_id = request_id
16
+ @root_event = nil
17
+ @current_event = nil
18
+ @sequence = []
19
+ end
20
+
21
+ def branch(event:)
22
+ @sequence << event
23
+
24
+ if @root_event.nil?
25
+ @root_event = event
26
+ @current_event = event
27
+ else
28
+ @current_event.children << event
29
+ end
30
+
31
+ trigger action: :branch, event: BranchEvent.new(event_tree: self, event:)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Low
4
+ module Support
5
+ class PoolHash < Hash
6
+ def initialize(max_size)
7
+ @max_size = max_size
8
+
9
+ super()
10
+ end
11
+
12
+ def add(key, value)
13
+ # Prune the hash when a new item added.
14
+ if size >= @max_size && !key?(key)
15
+ # TODO: Notify event pool that item was removed.
16
+ _old_key, _old_value = shift
17
+ end
18
+
19
+ self[key] = value
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Low
4
+ module Support
5
+ module ValueObject
6
+ def ==(other) = other.class == self.class
7
+ def eql?(other) = self == other
8
+ def hash = [self.class].hash
9
+ end
10
+ end
11
+ end
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Low
4
- EVENT_VERSION = '0.3.1'
4
+ EVENT_VERSION = '0.5.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: low_event
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - maedi
@@ -51,6 +51,20 @@ dependencies:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: providers
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
54
68
  description: Events and observers for event-driven applications
55
69
  email:
56
70
  - maediprichard@gmail.com
@@ -59,12 +73,18 @@ extensions: []
59
73
  extra_rdoc_files: []
60
74
  files:
61
75
  - lib/events/event.rb
76
+ - lib/events/hidden_event.rb
62
77
  - lib/events/render_event.rb
63
78
  - lib/events/request_event.rb
64
79
  - lib/events/response_event.rb
65
80
  - lib/events/status_event.rb
66
81
  - lib/factories/response_factory.rb
67
82
  - lib/low_event.rb
83
+ - lib/pool/branch_event.rb
84
+ - lib/pool/event_pool.rb
85
+ - lib/pool/event_tree.rb
86
+ - lib/support/pool_hash.rb
87
+ - lib/support/value_object.rb
68
88
  - lib/version.rb
69
89
  homepage: https://github.com/low-rb/low_event
70
90
  licenses: []
@@ -85,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
105
  - !ruby/object:Gem::Version
86
106
  version: '0'
87
107
  requirements: []
88
- rubygems_version: 3.7.2
108
+ rubygems_version: 4.0.6
89
109
  specification_version: 4
90
110
  summary: Observable events
91
111
  test_files: []