sourced 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,4 @@
1
+ module Sourced
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
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: []