sourced 0.0.1
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 +7 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +5 -0
- data/README.md +34 -0
- data/Rakefile +8 -0
- data/config.ru +0 -0
- data/examples/cart.rb +229 -0
- data/examples/workers.rb +5 -0
- data/lib/sourced/backends/active_record_backend.rb +184 -0
- data/lib/sourced/backends/sequel_backend.rb +387 -0
- data/lib/sourced/backends/test_backend.rb +273 -0
- data/lib/sourced/command_context.rb +46 -0
- data/lib/sourced/configuration.rb +39 -0
- data/lib/sourced/consumer.rb +42 -0
- data/lib/sourced/decide.rb +50 -0
- data/lib/sourced/decider.rb +251 -0
- data/lib/sourced/evolve.rb +102 -0
- data/lib/sourced/message.rb +202 -0
- data/lib/sourced/projector.rb +131 -0
- data/lib/sourced/rails/install_generator.rb +57 -0
- data/lib/sourced/rails/railtie.rb +16 -0
- data/lib/sourced/rails/templates/bin_sors +8 -0
- data/lib/sourced/rails/templates/create_sors_tables.rb.erb +55 -0
- data/lib/sourced/react.rb +57 -0
- data/lib/sourced/router.rb +148 -0
- data/lib/sourced/supervisor.rb +49 -0
- data/lib/sourced/sync.rb +80 -0
- data/lib/sourced/types.rb +24 -0
- data/lib/sourced/version.rb +5 -0
- data/lib/sourced/worker.rb +93 -0
- data/lib/sourced.rb +42 -0
- data/sig/sors.rbs +4 -0
- metadata +103 -0
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'console' # comes with Async
|
4
|
+
require 'sourced/router' # comes with Async
|
5
|
+
|
6
|
+
module Sourced
|
7
|
+
class Worker
|
8
|
+
def self.drain
|
9
|
+
new.drain
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.tick
|
13
|
+
new.tick
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :name
|
17
|
+
|
18
|
+
def initialize(
|
19
|
+
logger: Sourced.config.logger,
|
20
|
+
name: SecureRandom.hex(4),
|
21
|
+
poll_interval: 0.01
|
22
|
+
)
|
23
|
+
@logger = logger
|
24
|
+
@running = false
|
25
|
+
@name = [Process.pid, name].join('-')
|
26
|
+
@poll_interval = poll_interval
|
27
|
+
# TODO: If reactors have a :weight, we can use that
|
28
|
+
# to populate this array according to the weight
|
29
|
+
# so that some reactors are picked more often than others
|
30
|
+
@reactors = Router.async_reactors.filter do |r|
|
31
|
+
r.handled_events.any?
|
32
|
+
end.to_a.shuffle
|
33
|
+
@reactor_index = 0
|
34
|
+
end
|
35
|
+
|
36
|
+
def stop
|
37
|
+
@running = false
|
38
|
+
end
|
39
|
+
|
40
|
+
def poll
|
41
|
+
if @reactors.empty?
|
42
|
+
logger.warn "Worker #{name}: No reactors to poll"
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
|
46
|
+
@running = true
|
47
|
+
while @running
|
48
|
+
tick
|
49
|
+
# This sleep seems to be necessary or workers in differet processes will not be able to get the lock
|
50
|
+
sleep @poll_interval
|
51
|
+
dispatch_next_command.tap do |c|
|
52
|
+
sleep @poll_interval if c
|
53
|
+
end
|
54
|
+
end
|
55
|
+
logger.info "Worker #{name}: Polling stopped"
|
56
|
+
end
|
57
|
+
|
58
|
+
# Drain all reactors
|
59
|
+
# And all scheduled commands
|
60
|
+
def drain
|
61
|
+
@reactors.each do |reactor|
|
62
|
+
loop do
|
63
|
+
event = tick(reactor)
|
64
|
+
break unless event
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
loop do
|
69
|
+
cmd = dispatch_next_command
|
70
|
+
break unless cmd
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def tick(reactor = next_reactor)
|
75
|
+
Router.handle_next_event_for_reactor(reactor, name)
|
76
|
+
end
|
77
|
+
|
78
|
+
def dispatch_next_command
|
79
|
+
Router.dispatch_next_command
|
80
|
+
end
|
81
|
+
|
82
|
+
def next_reactor
|
83
|
+
@reactor_index = 0 if @reactor_index >= @reactors.size
|
84
|
+
reactor = @reactors[@reactor_index]
|
85
|
+
@reactor_index += 1
|
86
|
+
reactor
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
attr_reader :logger
|
92
|
+
end
|
93
|
+
end
|
data/lib/sourced.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'sourced/version'
|
4
|
+
|
5
|
+
require 'sourced/message'
|
6
|
+
|
7
|
+
module Sourced
|
8
|
+
class Error < StandardError; end
|
9
|
+
ConcurrentAppendError = Class.new(Error)
|
10
|
+
ConcurrentAckError = Class.new(Error)
|
11
|
+
|
12
|
+
def self.config
|
13
|
+
@config ||= Configuration.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.configure(&)
|
17
|
+
yield config if block_given?
|
18
|
+
config.freeze
|
19
|
+
config
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.message_method_name(prefix, name)
|
23
|
+
"__handle_#{prefix}_#{name.split('::').map(&:downcase).join('_')}"
|
24
|
+
end
|
25
|
+
|
26
|
+
DeciderInterface = Types::Interface[:handled_commands, :handle_command]
|
27
|
+
ReactorInterface = Types::Interface[:consumer_info, :handled_events, :handle_events]
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'sourced/consumer'
|
31
|
+
require 'sourced/decide'
|
32
|
+
require 'sourced/evolve'
|
33
|
+
require 'sourced/react'
|
34
|
+
require 'sourced/sync'
|
35
|
+
require 'sourced/configuration'
|
36
|
+
require 'sourced/router'
|
37
|
+
require 'sourced/message'
|
38
|
+
require 'sourced/decider'
|
39
|
+
require 'sourced/projector'
|
40
|
+
require 'sourced/supervisor'
|
41
|
+
require 'sourced/command_context'
|
42
|
+
require 'sourced/rails/railtie' if defined?(Rails::Railtie)
|
data/sig/sors.rbs
ADDED
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sourced
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ismael Celis
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-12-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: async
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: plumb
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.0.9
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.0.9
|
41
|
+
description:
|
42
|
+
email:
|
43
|
+
- ismaelct@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".rspec"
|
49
|
+
- CHANGELOG.md
|
50
|
+
- README.md
|
51
|
+
- Rakefile
|
52
|
+
- config.ru
|
53
|
+
- examples/cart.rb
|
54
|
+
- examples/workers.rb
|
55
|
+
- lib/sourced.rb
|
56
|
+
- lib/sourced/backends/active_record_backend.rb
|
57
|
+
- lib/sourced/backends/sequel_backend.rb
|
58
|
+
- lib/sourced/backends/test_backend.rb
|
59
|
+
- lib/sourced/command_context.rb
|
60
|
+
- lib/sourced/configuration.rb
|
61
|
+
- lib/sourced/consumer.rb
|
62
|
+
- lib/sourced/decide.rb
|
63
|
+
- lib/sourced/decider.rb
|
64
|
+
- lib/sourced/evolve.rb
|
65
|
+
- lib/sourced/message.rb
|
66
|
+
- lib/sourced/projector.rb
|
67
|
+
- lib/sourced/rails/install_generator.rb
|
68
|
+
- lib/sourced/rails/railtie.rb
|
69
|
+
- lib/sourced/rails/templates/bin_sors
|
70
|
+
- lib/sourced/rails/templates/create_sors_tables.rb.erb
|
71
|
+
- lib/sourced/react.rb
|
72
|
+
- lib/sourced/router.rb
|
73
|
+
- lib/sourced/supervisor.rb
|
74
|
+
- lib/sourced/sync.rb
|
75
|
+
- lib/sourced/types.rb
|
76
|
+
- lib/sourced/version.rb
|
77
|
+
- lib/sourced/worker.rb
|
78
|
+
- sig/sors.rbs
|
79
|
+
homepage: https://github.com/ismaelcelis/sourced
|
80
|
+
licenses: []
|
81
|
+
metadata:
|
82
|
+
homepage_uri: https://github.com/ismaelcelis/sourced
|
83
|
+
source_code_uri: https://github.com/ismaelcelis/sourced
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 3.0.0
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubygems_version: 3.5.23
|
100
|
+
signing_key:
|
101
|
+
specification_version: 4
|
102
|
+
summary: Decide, Evolve, React
|
103
|
+
test_files: []
|