active_saga 0.1.0 → 0.1.3

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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/ADAPTERS.md +6 -6
  3. data/CHANGELOG.md +1 -1
  4. data/GUIDE.md +10 -10
  5. data/LICENSE +1 -1
  6. data/README.md +51 -51
  7. data/lib/{active_workflow → active_saga}/backoff.rb +1 -1
  8. data/lib/{active_workflow → active_saga}/configuration.rb +3 -3
  9. data/lib/{active_workflow → active_saga}/context.rb +1 -1
  10. data/lib/{active_workflow → active_saga}/dsl/options.rb +8 -8
  11. data/lib/{active_workflow → active_saga}/dsl/signals.rb +5 -5
  12. data/lib/{active_workflow → active_saga}/dsl/steps.rb +11 -11
  13. data/lib/{active_workflow → active_saga}/errors.rb +1 -1
  14. data/lib/{active_workflow → active_saga}/execution.rb +5 -5
  15. data/lib/{active_workflow → active_saga}/jobs/runner_job.rb +8 -8
  16. data/lib/active_saga/railtie.rb +17 -0
  17. data/lib/{active_workflow → active_saga}/serializers/json.rb +1 -1
  18. data/lib/{active_workflow → active_saga}/stores/active_record.rb +34 -34
  19. data/lib/{active_workflow → active_saga}/stores/base.rb +4 -4
  20. data/lib/{active_workflow → active_saga}/task.rb +5 -5
  21. data/lib/active_saga/version.rb +5 -0
  22. data/lib/{active_workflow → active_saga}/workflow.rb +5 -5
  23. data/lib/{active_workflow.rb → active_saga.rb} +21 -21
  24. data/lib/generators/{active_workflow → active_saga}/install/install_generator.rb +3 -13
  25. data/lib/generators/active_saga/install/templates/initializer.rb +8 -0
  26. data/lib/generators/{active_workflow/install/templates/migrations/create_active_workflow_tables.rb → active_saga/install/templates/migrations/create_active_saga_tables.rb} +14 -14
  27. data/lib/generators/{active_workflow → active_saga}/install/templates/sample_workflow.rb +2 -2
  28. data/lib/generators/{active_workflow → active_saga}/workflow/templates/workflow.rb +1 -1
  29. data/lib/generators/{active_workflow → active_saga}/workflow/workflow_generator.rb +1 -1
  30. metadata +26 -26
  31. data/lib/active_workflow/railtie.rb +0 -17
  32. data/lib/active_workflow/version.rb +0 -5
  33. data/lib/generators/active_workflow/install/templates/initializer.rb +0 -8
@@ -1,27 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ActiveWorkflow
3
+ module ActiveSaga
4
4
  module Jobs
5
5
  # Executes workflow transitions within Active Job.
6
6
  class RunnerJob < ActiveJob::Base
7
- queue_as :active_workflow
7
+ queue_as :active_saga
8
8
 
9
9
  # We want retries for transient errors only; user-defined retries handled within workflow.
10
10
  retry_on ActiveRecord::Deadlocked, wait: 1.second, attempts: 5 if defined?(ActiveRecord::Deadlocked)
11
11
 
12
12
  def perform(execution_id)
13
- execution = ActiveWorkflow.configuration.store.load_execution(execution_id)
13
+ execution = ActiveSaga.configuration.store.load_execution(execution_id)
14
14
  if execution
15
15
  workflow = execution.workflow_class || "UnknownWorkflow"
16
16
  step = execution.cursor_step || "pending"
17
- ActiveWorkflow.configuration.logger.info(
18
- "ActiveWorkflow::RunnerJob executing #{workflow}##{step} (execution=#{execution_id}) (state=#{execution.state})"
17
+ ActiveSaga.configuration.logger.info(
18
+ "ActiveSaga::RunnerJob executing #{workflow}##{step} (execution=#{execution_id}) (state=#{execution.state})"
19
19
  )
20
20
  end
21
21
 
22
- ActiveWorkflow.configuration.store!.process_execution(execution_id)
23
- rescue ActiveWorkflow::Errors::InvalidWorkflow => e
24
- ActiveWorkflow.configuration.logger.error("ActiveWorkflow invalid workflow: #{e.message}")
22
+ ActiveSaga.configuration.store!.process_execution(execution_id)
23
+ rescue ActiveSaga::Errors::InvalidWorkflow => e
24
+ ActiveSaga.configuration.logger.error("ActiveSaga invalid workflow: #{e.message}")
25
25
  raise
26
26
  end
27
27
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/railtie"
4
+
5
+ module ActiveSaga
6
+ class Railtie < Rails::Railtie
7
+ initializer "active_saga.configure" do |_app|
8
+ ActiveSaga.configure do |config|
9
+ config.logger ||= Rails.logger
10
+ end
11
+ end
12
+
13
+ rake_tasks do
14
+ load "active_saga/tasks.rake" if File.exist?(File.join(__dir__, "../../tasks.rake"))
15
+ end
16
+ end
17
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "json"
4
4
 
5
- module ActiveWorkflow
5
+ module ActiveSaga
6
6
  module Serializers
7
7
  # Simple JSON wrapper allowing custom serialization strategies.
8
8
  class Json
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "active_record"
4
4
 
5
- module ActiveWorkflow
5
+ module ActiveSaga
6
6
  module Stores
7
7
  # ActiveRecord-backed persistence implementation.
8
8
  class ActiveRecord < Base
@@ -10,26 +10,26 @@ module ActiveWorkflow
10
10
 
11
11
  module Models
12
12
  class Execution < ::ActiveRecord::Base
13
- self.table_name = "aw_executions"
13
+ self.table_name = "as_executions"
14
14
 
15
15
  has_many :steps,
16
- class_name: "ActiveWorkflow::Stores::ActiveRecord::Models::Step",
16
+ class_name: "ActiveSaga::Stores::ActiveRecord::Models::Step",
17
17
  foreign_key: :execution_id,
18
18
  inverse_of: :execution,
19
19
  dependent: :destroy
20
20
 
21
21
  has_many :events,
22
- class_name: "ActiveWorkflow::Stores::ActiveRecord::Models::Event",
22
+ class_name: "ActiveSaga::Stores::ActiveRecord::Models::Event",
23
23
  foreign_key: :execution_id,
24
24
  inverse_of: :execution,
25
25
  dependent: :destroy
26
26
  end
27
27
 
28
28
  class Step < ::ActiveRecord::Base
29
- self.table_name = "aw_steps"
29
+ self.table_name = "as_steps"
30
30
 
31
31
  belongs_to :execution,
32
- class_name: "ActiveWorkflow::Stores::ActiveRecord::Models::Execution",
32
+ class_name: "ActiveSaga::Stores::ActiveRecord::Models::Execution",
33
33
  foreign_key: :execution_id,
34
34
  inverse_of: :steps
35
35
 
@@ -49,10 +49,10 @@ module ActiveWorkflow
49
49
  end
50
50
 
51
51
  class Event < ::ActiveRecord::Base
52
- self.table_name = "aw_events"
52
+ self.table_name = "as_events"
53
53
 
54
54
  belongs_to :execution,
55
- class_name: "ActiveWorkflow::Stores::ActiveRecord::Models::Execution",
55
+ class_name: "ActiveSaga::Stores::ActiveRecord::Models::Execution",
56
56
  foreign_key: :execution_id,
57
57
  inverse_of: :events
58
58
  end
@@ -93,7 +93,7 @@ module ActiveWorkflow
93
93
 
94
94
  if steps.empty?
95
95
  record.update!(state: "completed", cursor_step: nil, completed_at: now)
96
- ActiveSupport::Notifications.instrument("active_workflow.execution.completed",
96
+ ActiveSupport::Notifications.instrument("active_saga.execution.completed",
97
97
  execution_id: record.id,
98
98
  workflow: workflow_class)
99
99
  end
@@ -129,9 +129,9 @@ module ActiveWorkflow
129
129
 
130
130
  def enqueue_runner(execution_id, run_at: nil)
131
131
  if run_at
132
- ActiveWorkflow::Jobs::RunnerJob.set(wait_until: run_at).perform_later(execution_id)
132
+ ActiveSaga::Jobs::RunnerJob.set(wait_until: run_at).perform_later(execution_id)
133
133
  else
134
- ActiveWorkflow::Jobs::RunnerJob.perform_later(execution_id)
134
+ ActiveSaga::Jobs::RunnerJob.perform_later(execution_id)
135
135
  end
136
136
  end
137
137
 
@@ -157,10 +157,10 @@ module ActiveWorkflow
157
157
  return build_execution(execution)
158
158
  end
159
159
 
160
- raise ActiveWorkflow::Errors::StepNotWaiting, "Step #{step_name} is not waiting" unless step&.waiting?
160
+ raise ActiveSaga::Errors::StepNotWaiting, "Step #{step_name} is not waiting" unless step&.waiting?
161
161
 
162
162
  if idempotency_key && step.completion_idempotency_key.present? && step.completion_idempotency_key != idempotency_key
163
- raise ActiveWorkflow::Errors::AsyncCompletionConflict, "Completion idempotency mismatch"
163
+ raise ActiveSaga::Errors::AsyncCompletionConflict, "Completion idempotency mismatch"
164
164
  end
165
165
 
166
166
  return build_execution(execution) if step.completion_idempotency_key.present? && step.completion_idempotency_key == idempotency_key
@@ -187,7 +187,7 @@ module ActiveWorkflow
187
187
  completed_at: clock.call
188
188
  )
189
189
 
190
- ActiveSupport::Notifications.instrument("active_workflow.step.completed_async",
190
+ ActiveSupport::Notifications.instrument("active_saga.step.completed_async",
191
191
  execution_id: execution.id,
192
192
  step: step.name,
193
193
  workflow: execution.workflow_class)
@@ -201,7 +201,7 @@ module ActiveWorkflow
201
201
  def fail_step!(execution_id, step_name, error_class:, message:, details:, idempotency_key: nil)
202
202
  with_execution_lock(execution_id) do |execution|
203
203
  step = execution.steps.lock.find_by(name: step_name.to_s)
204
- raise ActiveWorkflow::Errors::StepNotWaiting, "Step #{step_name} is not waiting" unless step&.waiting?
204
+ raise ActiveSaga::Errors::StepNotWaiting, "Step #{step_name} is not waiting" unless step&.waiting?
205
205
 
206
206
  definition = step_definition(execution, step)
207
207
  current_attempts = step.attempts.to_i
@@ -212,7 +212,7 @@ module ActiveWorkflow
212
212
  attempts: current_attempts,
213
213
  async: true)
214
214
 
215
- ActiveSupport::Notifications.instrument("active_workflow.step.failed_async",
215
+ ActiveSupport::Notifications.instrument("active_saga.step.failed_async",
216
216
  execution_id: execution.id,
217
217
  step: step.name,
218
218
  workflow: execution.workflow_class,
@@ -245,7 +245,7 @@ module ActiveWorkflow
245
245
  with_execution_lock(execution_id) do |execution|
246
246
  Models::Event.create!(execution:, name: name.to_s, payload: payload)
247
247
 
248
- ActiveSupport::Notifications.instrument("active_workflow.signal.received",
248
+ ActiveSupport::Notifications.instrument("active_saga.signal.received",
249
249
  execution_id: execution.id,
250
250
  signal: name)
251
251
 
@@ -273,7 +273,7 @@ module ActiveWorkflow
273
273
  cancelled_at: clock.call
274
274
  )
275
275
 
276
- ActiveSupport::Notifications.instrument("active_workflow.execution.cancelled",
276
+ ActiveSupport::Notifications.instrument("active_saga.execution.cancelled",
277
277
  execution_id: execution.id,
278
278
  workflow: execution.workflow_class,
279
279
  reason: reason)
@@ -283,7 +283,7 @@ module ActiveWorkflow
283
283
  end
284
284
 
285
285
  def context_from(execution)
286
- ActiveWorkflow::Context.new(serializer.load(execution.ctx))
286
+ ActiveSaga::Context.new(serializer.load(execution.ctx))
287
287
  end
288
288
 
289
289
  def persist_context(execution, ctx)
@@ -291,7 +291,7 @@ module ActiveWorkflow
291
291
  end
292
292
 
293
293
  def build_execution(record)
294
- ActiveWorkflow::Execution.new(
294
+ ActiveSaga::Execution.new(
295
295
  id: record.id,
296
296
  workflow_class: record.workflow_class,
297
297
  state: record.state,
@@ -333,7 +333,7 @@ module ActiveWorkflow
333
333
  state: "completed",
334
334
  completed_at: clock.call
335
335
  )
336
- ActiveSupport::Notifications.instrument("active_workflow.execution.completed",
336
+ ActiveSupport::Notifications.instrument("active_saga.execution.completed",
337
337
  execution_id: execution.id,
338
338
  workflow: execution.workflow_class)
339
339
  end
@@ -361,13 +361,13 @@ module ActiveWorkflow
361
361
 
362
362
  if current_attempts < max_attempts
363
363
  retry_index = [current_attempts, 1].max
364
- delay = ActiveWorkflow::Backoff.calculate(retry_config, attempts: retry_index)
364
+ delay = ActiveSaga::Backoff.calculate(retry_config, attempts: retry_index)
365
365
  scheduled_at = clock.call + delay
366
366
 
367
367
  step.update!(state: "pending", attempts: current_attempts, scheduled_at: scheduled_at)
368
368
  execution.update!(state: "running", cursor_step: definition.name)
369
369
 
370
- ActiveSupport::Notifications.instrument("active_workflow.retry.scheduled",
370
+ ActiveSupport::Notifications.instrument("active_saga.retry.scheduled",
371
371
  execution_id: execution.id,
372
372
  workflow: execution.workflow_class,
373
373
  step: step.name,
@@ -384,7 +384,7 @@ module ActiveWorkflow
384
384
  step.update!(state: "failed")
385
385
  run_compensations!(execution, upto: step.position)
386
386
  execution.update!(state: "failed", cursor_step: nil)
387
- ActiveSupport::Notifications.instrument("active_workflow.execution.failed",
387
+ ActiveSupport::Notifications.instrument("active_saga.execution.failed",
388
388
  execution_id: execution.id,
389
389
  workflow: execution.workflow_class,
390
390
  step: step.name)
@@ -406,7 +406,7 @@ module ActiveWorkflow
406
406
  next if step.state == "compensated"
407
407
  next unless compensate
408
408
 
409
- ActiveSupport::Notifications.instrument("active_workflow.step.compensating",
409
+ ActiveSupport::Notifications.instrument("active_saga.step.compensating",
410
410
  execution_id: execution.id,
411
411
  step: definition.name) do
412
412
  case compensate
@@ -464,7 +464,7 @@ module ActiveWorkflow
464
464
  if skip_step?(workflow, definition)
465
465
  mark_skipped(step, definition)
466
466
  store.persist_context(execution, workflow.ctx)
467
- ActiveSupport::Notifications.instrument("active_workflow.step.skipped",
467
+ ActiveSupport::Notifications.instrument("active_saga.step.skipped",
468
468
  execution_id: execution.id, step: definition.name, workflow: workflow_class.name)
469
469
  process! # continue to next
470
470
  return
@@ -475,7 +475,7 @@ module ActiveWorkflow
475
475
  step.update!(state: "running", attempts: attempt, started_at: now, scheduled_at: nil)
476
476
  execution.update!(state: "running", cursor_step: definition.name)
477
477
 
478
- ActiveSupport::Notifications.instrument("active_workflow.step.started",
478
+ ActiveSupport::Notifications.instrument("active_saga.step.started",
479
479
  execution_id: execution.id,
480
480
  workflow: workflow_class.name,
481
481
  step: definition.name,
@@ -489,11 +489,11 @@ module ActiveWorkflow
489
489
  when :complete
490
490
  store.persist_context(execution, workflow.ctx)
491
491
  step.update!(state: "completed", completed_at: store.clock.call)
492
- ActiveSupport::Notifications.instrument("active_workflow.step.completed",
492
+ ActiveSupport::Notifications.instrument("active_saga.step.completed",
493
493
  execution_id: execution.id, workflow: workflow_class.name, step: definition.name)
494
494
  new_state = next_state_after(step)
495
495
  execution.update!(state: new_state, cursor_step: next_step_name(step))
496
- ActiveSupport::Notifications.instrument("active_workflow.execution.completed",
496
+ ActiveSupport::Notifications.instrument("active_saga.execution.completed",
497
497
  execution_id: execution.id,
498
498
  workflow: execution.workflow_class) if new_state == "completed"
499
499
  process!
@@ -501,11 +501,11 @@ module ActiveWorkflow
501
501
  # Synchronous result returned.
502
502
  store.persist_context(execution, workflow.ctx)
503
503
  step.update!(state: "completed", completed_at: store.clock.call)
504
- ActiveSupport::Notifications.instrument("active_workflow.step.completed",
504
+ ActiveSupport::Notifications.instrument("active_saga.step.completed",
505
505
  execution_id: execution.id, workflow: workflow_class.name, step: definition.name, result: result)
506
506
  new_state = next_state_after(step)
507
507
  execution.update!(state: new_state, cursor_step: next_step_name(step))
508
- ActiveSupport::Notifications.instrument("active_workflow.execution.completed",
508
+ ActiveSupport::Notifications.instrument("active_saga.execution.completed",
509
509
  execution_id: execution.id,
510
510
  workflow: execution.workflow_class) if new_state == "completed"
511
511
  process!
@@ -526,7 +526,7 @@ module ActiveWorkflow
526
526
  next unless step.timeout_at && step.timeout_at <= now
527
527
 
528
528
  definition = step_definition(step)
529
- ActiveSupport::Notifications.instrument("active_workflow.step.timeout",
529
+ ActiveSupport::Notifications.instrument("active_saga.step.timeout",
530
530
  execution_id: execution.id,
531
531
  workflow: execution.workflow_class,
532
532
  step: step.name)
@@ -624,7 +624,7 @@ module ActiveWorkflow
624
624
  )
625
625
  execution.update!(state: "waiting", cursor_step: definition.name)
626
626
 
627
- ActiveSupport::Notifications.instrument("active_workflow.step.waiting",
627
+ ActiveSupport::Notifications.instrument("active_saga.step.waiting",
628
628
  execution_id: execution.id, workflow: execution.workflow_class, step: definition.name)
629
629
 
630
630
  store.enqueue_runner(execution.id, run_at: timeout_at) if timeout_at
@@ -645,7 +645,7 @@ module ActiveWorkflow
645
645
  attempts: attempts
646
646
  )
647
647
 
648
- ActiveSupport::Notifications.instrument("active_workflow.step.failed",
648
+ ActiveSupport::Notifications.instrument("active_saga.step.failed",
649
649
  execution_id: execution.id,
650
650
  workflow: execution.workflow_class,
651
651
  step: definition.name,
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ActiveWorkflow
3
+ module ActiveSaga
4
4
  module Stores
5
5
  # Base interface for persistence adapters.
6
6
  class Base
7
7
  attr_reader :logger, :serializer, :clock
8
8
 
9
- def initialize(logger: ActiveWorkflow.configuration.logger,
10
- serializer: ActiveWorkflow.configuration.serializer,
11
- clock: ActiveWorkflow.configuration.clock)
9
+ def initialize(logger: ActiveSaga.configuration.logger,
10
+ serializer: ActiveSaga.configuration.serializer,
11
+ clock: ActiveSaga.configuration.clock)
12
12
  @logger = logger
13
13
  @serializer = serializer
14
14
  @clock = clock
@@ -1,19 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ActiveWorkflow
3
+ module ActiveSaga
4
4
  # Base class for reusable workflow tasks.
5
5
  class Task
6
6
  class << self
7
- attr_reader :_aw_async_options
7
+ attr_reader :_as_async_options
8
8
 
9
9
  def async!(**options)
10
- @_aw_async_options = options.deep_symbolize_keys
10
+ @_as_async_options = options.deep_symbolize_keys
11
11
  end
12
12
 
13
13
  def async_options
14
- _aw_async_options || {}
14
+ _as_async_options || {}
15
+ end
15
16
  end
16
- end
17
17
 
18
18
  def initialize(context)
19
19
  @context = context
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSaga
4
+ VERSION = "0.1.3"
5
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ActiveWorkflow
3
+ module ActiveSaga
4
4
  # Base class for defining workflows.
5
5
  class Workflow
6
6
  extend DSL::Options
@@ -15,12 +15,12 @@ module ActiveWorkflow
15
15
  explicit_idempotency_key = options.delete(:idempotency_key)
16
16
  metadata = options.delete(:metadata) { {} }
17
17
 
18
- context = ActiveWorkflow::Context.new(options)
18
+ context = ActiveSaga::Context.new(options)
19
19
  workflow = new(context: context)
20
20
  workflow.before_start
21
21
 
22
22
  idempotency_key = explicit_idempotency_key || workflow.compute_idempotency_key
23
- store = ActiveWorkflow.configuration.store!
23
+ store = ActiveSaga.configuration.store!
24
24
 
25
25
  execution = store.start_execution(
26
26
  workflow_class: name,
@@ -31,7 +31,7 @@ module ActiveWorkflow
31
31
  metadata: (metadata || {}).deep_symbolize_keys
32
32
  )
33
33
 
34
- ActiveSupport::Notifications.instrument("active_workflow.execution.started",
34
+ ActiveSupport::Notifications.instrument("active_saga.execution.started",
35
35
  execution_id: execution.id, workflow: name)
36
36
 
37
37
  execution
@@ -94,7 +94,7 @@ module ActiveWorkflow
94
94
  when :wait
95
95
  :waiting
96
96
  else
97
- raise ActiveWorkflow::Errors::InvalidStep, "Unknown style #{step_definition.style}"
97
+ raise ActiveSaga::Errors::InvalidStep, "Unknown style #{step_definition.style}"
98
98
  end
99
99
  end
100
100
 
@@ -10,33 +10,33 @@ require "active_support/inflector"
10
10
  require "active_support/notifications"
11
11
  require "active_job"
12
12
 
13
- require_relative "active_workflow/version"
14
- require_relative "active_workflow/errors"
15
- require_relative "active_workflow/configuration"
16
- require_relative "active_workflow/context"
17
- require_relative "active_workflow/execution"
18
- require_relative "active_workflow/backoff"
19
- require_relative "active_workflow/dsl/options"
20
- require_relative "active_workflow/dsl/steps"
21
- require_relative "active_workflow/dsl/signals"
22
- require_relative "active_workflow/workflow"
23
- require_relative "active_workflow/task"
24
- require_relative "active_workflow/jobs/runner_job"
25
- require_relative "active_workflow/stores/base"
26
- require_relative "active_workflow/stores/active_record"
27
- require_relative "active_workflow/serializers/json"
28
- require_relative "active_workflow/railtie" if defined?(Rails::Railtie)
13
+ require_relative "active_saga/version"
14
+ require_relative "active_saga/errors"
15
+ require_relative "active_saga/configuration"
16
+ require_relative "active_saga/context"
17
+ require_relative "active_saga/execution"
18
+ require_relative "active_saga/backoff"
19
+ require_relative "active_saga/dsl/options"
20
+ require_relative "active_saga/dsl/steps"
21
+ require_relative "active_saga/dsl/signals"
22
+ require_relative "active_saga/workflow"
23
+ require_relative "active_saga/task"
24
+ require_relative "active_saga/jobs/runner_job"
25
+ require_relative "active_saga/stores/base"
26
+ require_relative "active_saga/stores/active_record"
27
+ require_relative "active_saga/serializers/json"
28
+ require_relative "active_saga/railtie" if defined?(Rails::Railtie)
29
29
 
30
- module ActiveWorkflow
30
+ module ActiveSaga
31
31
  class << self
32
- # @return [ActiveWorkflow::Configuration]
32
+ # @return [ActiveSaga::Configuration]
33
33
  def configuration
34
34
  @configuration ||= Configuration.new
35
35
  end
36
36
 
37
37
  # Yields global configuration block and memoizes the configuration instance.
38
38
  #
39
- # @yieldparam [ActiveWorkflow::Configuration] config
39
+ # @yieldparam [ActiveSaga::Configuration] config
40
40
  def configure
41
41
  yield(configuration)
42
42
  end
@@ -48,7 +48,7 @@ module ActiveWorkflow
48
48
 
49
49
  # Delegates the store accessor for convenience.
50
50
  #
51
- # @return [ActiveWorkflow::Stores::Base]
51
+ # @return [ActiveSaga::Stores::Base]
52
52
  def store
53
53
  configuration.store!
54
54
  end
@@ -91,7 +91,7 @@ module ActiveWorkflow
91
91
  private
92
92
 
93
93
  def with_instrumentation(action, execution_id, step_name)
94
- ActiveSupport::Notifications.instrument("active_workflow.step.#{action}",
94
+ ActiveSupport::Notifications.instrument("active_saga.step.#{action}",
95
95
  execution_id: execution_id,
96
96
  step: step_name.to_s) { yield }
97
97
  end
@@ -3,7 +3,7 @@
3
3
  require "rails/generators"
4
4
  require "rails/generators/active_record"
5
5
 
6
- module ActiveWorkflow
6
+ module ActiveSaga
7
7
  module Generators
8
8
  class InstallGenerator < Rails::Generators::Base
9
9
  include ActiveRecord::Generators::Migration
@@ -16,11 +16,11 @@ module ActiveWorkflow
16
16
  def copy_initializer
17
17
  return if options[:skip_initializer]
18
18
 
19
- template "initializer.rb", "config/initializers/active_workflow.rb"
19
+ template "initializer.rb", "config/initializers/active_saga.rb"
20
20
  end
21
21
 
22
22
  def copy_migration
23
- migration_template "migrations/create_active_workflow_tables.rb", "db/migrate/create_active_workflow_tables.rb"
23
+ migration_template "migrations/create_active_saga_tables.rb", "db/migrate/create_active_saga_tables.rb"
24
24
  end
25
25
 
26
26
  def copy_sample_workflow
@@ -28,16 +28,6 @@ module ActiveWorkflow
28
28
 
29
29
  template "sample_workflow.rb", "app/workflows/sample_workflow.rb"
30
30
  end
31
-
32
- private
33
-
34
- def self.next_migration_number(dirname)
35
- if ActiveRecord::Base.timestamped_migrations
36
- Time.now.utc.strftime("%Y%m%d%H%M%S")
37
- else
38
- format("%03d", (current_migration_number(dirname) + 1))
39
- end
40
- end
41
31
  end
42
32
  end
43
33
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ ActiveSaga.configure do |config|
4
+ config.logger = Rails.logger
5
+ config.clock = -> { Time.now.utc }
6
+ config.serializer = ActiveSaga::Serializers::Json.new
7
+ config.store = ActiveSaga::Stores::ActiveRecord.new
8
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class CreateActiveWorkflowTables < ActiveRecord::Migration[7.1]
3
+ class CreateActiveSagaTables < ActiveRecord::Migration[7.1]
4
4
  def change
5
- create_table :aw_executions do |t|
5
+ create_table :as_executions do |t|
6
6
  t.string :workflow_class, null: false
7
7
  t.string :state, null: false
8
8
  t.text :ctx, null: false
@@ -20,12 +20,12 @@ class CreateActiveWorkflowTables < ActiveRecord::Migration[7.1]
20
20
  t.timestamps
21
21
  end
22
22
 
23
- add_index :aw_executions, :workflow_class
24
- add_index :aw_executions, :state
25
- add_index :aw_executions, :idempotency_key, unique: true
23
+ add_index :as_executions, :workflow_class
24
+ add_index :as_executions, :state
25
+ add_index :as_executions, :idempotency_key, unique: true
26
26
 
27
- create_table :aw_steps do |t|
28
- t.references :execution, null: false, foreign_key: { to_table: :aw_executions }
27
+ create_table :as_steps do |t|
28
+ t.references :execution, null: false, foreign_key: { to_table: :as_executions }
29
29
  t.string :name, null: false
30
30
  t.string :style, null: false
31
31
  t.jsonb :options, null: false, default: {}
@@ -51,12 +51,12 @@ class CreateActiveWorkflowTables < ActiveRecord::Migration[7.1]
51
51
  t.timestamps
52
52
  end
53
53
 
54
- add_index :aw_steps, [:execution_id, :position]
55
- add_index :aw_steps, [:execution_id, :name]
56
- add_index :aw_steps, [:execution_id, :completion_idempotency_key], unique: true, where: "completion_idempotency_key IS NOT NULL"
54
+ add_index :as_steps, [:execution_id, :position]
55
+ add_index :as_steps, [:execution_id, :name]
56
+ add_index :as_steps, [:execution_id, :completion_idempotency_key], unique: true, where: "completion_idempotency_key IS NOT NULL"
57
57
 
58
- create_table :aw_events do |t|
59
- t.references :execution, null: false, foreign_key: { to_table: :aw_executions }
58
+ create_table :as_events do |t|
59
+ t.references :execution, null: false, foreign_key: { to_table: :as_executions }
60
60
  t.string :name, null: false
61
61
  t.jsonb :payload, null: false, default: {}
62
62
  t.datetime :consumed_at
@@ -64,7 +64,7 @@ class CreateActiveWorkflowTables < ActiveRecord::Migration[7.1]
64
64
  t.timestamps
65
65
  end
66
66
 
67
- add_index :aw_events, [:execution_id, :name]
68
- add_index :aw_events, [:execution_id, :name], where: "consumed_at IS NULL", name: "index_aw_events_unconsumed"
67
+ add_index :as_events, [:execution_id, :name]
68
+ add_index :as_events, [:execution_id, :name], where: "consumed_at IS NULL", name: "index_as_events_unconsumed"
69
69
  end
70
70
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class SampleWorkflow < ActiveWorkflow::Workflow
3
+ class SampleWorkflow < ActiveSaga::Workflow
4
4
  idempotency_key { "sample:#{ctx[:reference]}" }
5
5
  defaults retry: { max: 3, strategy: :exponential, first_delay: 2.seconds, jitter: true }
6
6
 
@@ -16,7 +16,7 @@ class SampleWorkflow < ActiveWorkflow::Workflow
16
16
  end
17
17
  end
18
18
 
19
- class RemoteExportTask < ActiveWorkflow::Task
19
+ class RemoteExportTask < ActiveSaga::Task
20
20
  async! timeout: 15.minutes
21
21
 
22
22
  def call(ctx)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class <%= class_name %> < ActiveWorkflow::Workflow
3
+ class <%= class_name %> < ActiveSaga::Workflow
4
4
  # idempotency_key { "#{name.underscore}:#{ctx[:resource_id]}" }
5
5
  # defaults retry: { max: 3, strategy: :exponential, first_delay: 2.seconds, jitter: true }
6
6
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "rails/generators"
4
4
 
5
- module ActiveWorkflow
5
+ module ActiveSaga
6
6
  module Generators
7
7
  class WorkflowGenerator < Rails::Generators::NamedBase
8
8
  source_root File.expand_path("templates", __dir__)