solid_objects 0.17.2 → 0.17.4

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.
@@ -0,0 +1,22 @@
1
+ # rbs_inline: enabled
2
+
3
+ class Checkout < SolidObjects::Actor
4
+ attribute :status, default: "open"
5
+ attribute :total_cents, default: 0
6
+ attribute :shipment_id, default: nil
7
+
8
+ def place(total_cents:)
9
+ return status unless status == "open"
10
+
11
+ self.status = "placed"
12
+ self.total_cents = total_cents
13
+ commit_action(:record_order, reference: actor_id, total_cents:)
14
+ emit(:request_shipment, order_reference: actor_id, on_success: :shipment_requested)
15
+ status
16
+ end
17
+
18
+ def shipment_requested(effect_id:, arguments:, result:)
19
+ self.status = "shipping"
20
+ self.shipment_id = result.fetch("shipment_id")
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ # rbs_inline: enabled
2
+
3
+ class Order < ApplicationRecord
4
+ def self.place_and_enqueue!(reference:, total_cents:)
5
+ order = create!(reference:, total_cents:)
6
+ ShipmentJob.perform_later(order_id: order.id)
7
+ order
8
+ end
9
+
10
+ def self.place_with_outbox!(reference:, total_cents:)
11
+ transaction do
12
+ order = create!(reference:, total_cents:)
13
+ OutboxMessage.create!(name: "request_shipment", arguments: { "order_id" => order.id })
14
+ order
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ # rbs_inline: enabled
2
+
3
+ class OutboxMessage < ApplicationRecord
4
+ JOBS = { "request_shipment" => ShipmentJob }.freeze
5
+
6
+ scope :pending, -> { where(delivered_at: nil).order(:id) }
7
+
8
+ def self.relay(limit: 100)
9
+ pending.limit(limit).each do |message|
10
+ JOBS.fetch(message.name).perform_later(**message.arguments.symbolize_keys)
11
+ message.update!(delivered_at: Time.current)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ # rbs_inline: enabled
2
+
3
+ class ShipmentJob < ApplicationJob
4
+ def perform(order_id:)
5
+ order = Order.find(order_id)
6
+ ShippingProvider.create_shipment(idempotency_key: "order-#{order.id}", order_reference: order.reference)
7
+ end
8
+ end
@@ -0,0 +1,12 @@
1
+ # rbs_inline: enabled
2
+
3
+ SolidObjects.register_commit_action(:record_order) do |arguments, _context|
4
+ Order.create!(reference: arguments.fetch("reference"), total_cents: arguments.fetch("total_cents"))
5
+ end
6
+
7
+ SolidObjects.register_effect(:request_shipment) do |arguments, context|
8
+ ShippingProvider.create_shipment(
9
+ idempotency_key: context.id,
10
+ order_reference: arguments.fetch("order_reference")
11
+ )
12
+ end
@@ -139,6 +139,7 @@ module SolidObjects
139
139
  break
140
140
  end
141
141
 
142
+ renew_lease if processed_count.positive? && lease_renewal_due?
142
143
  message = claim_next_message
143
144
  break unless message
144
145
 
@@ -123,6 +123,7 @@ module SolidObjects
123
123
  instance = Instance.lock.find_by(id: instance_id)
124
124
  next false unless instance
125
125
  next false unless owned_generation?(instance)
126
+ next false if ClaimedMessage.where(instance_id:).exists?
126
127
 
127
128
  instance.update!(
128
129
  activation_owner_id: nil,
@@ -1,5 +1,5 @@
1
1
  # rbs_inline: enabled
2
2
 
3
3
  module SolidObjects
4
- VERSION = "0.17.2"
4
+ VERSION = "0.17.4"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solid_objects
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.2
4
+ version: 0.17.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lucas Carlson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-10-08 00:00:00.000000000 Z
11
+ date: 2026-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actioncable
@@ -362,6 +362,10 @@ files:
362
362
  - docs/development.md
363
363
  - docs/effect-recovery.md
364
364
  - docs/fit.md
365
+ - docs/guides/expiring-reservations.md
366
+ - docs/guides/ordered-jobs.md
367
+ - docs/guides/race-conditions.md
368
+ - docs/guides/transactional-outbox.md
365
369
  - docs/implementation-plan.md
366
370
  - docs/local-testing.md
367
371
  - docs/migrating-existing-state.md
@@ -391,6 +395,21 @@ files:
391
395
  - examples/at_least_once/demo.rb
392
396
  - examples/at_least_once/effect_worker.rb
393
397
  - examples/at_least_once/sink.rb
398
+ - examples/guides/expiring_reservations/seat_inventory.rb
399
+ - examples/guides/ordered_jobs/account.rb
400
+ - examples/guides/ordered_jobs/apply_entry_job.rb
401
+ - examples/guides/ordered_jobs/apply_entry_unordered_job.rb
402
+ - examples/guides/ordered_jobs/create_ledger_entries.rb
403
+ - examples/guides/ordered_jobs/ledger_account.rb
404
+ - examples/guides/ordered_jobs/ledger_entry.rb
405
+ - examples/guides/ordered_jobs/solid_objects.rb
406
+ - examples/guides/race_conditions/event.rb
407
+ - examples/guides/race_conditions/event_tickets.rb
408
+ - examples/guides/transactional_outbox/checkout.rb
409
+ - examples/guides/transactional_outbox/order.rb
410
+ - examples/guides/transactional_outbox/outbox_message.rb
411
+ - examples/guides/transactional_outbox/shipment_job.rb
412
+ - examples/guides/transactional_outbox/solid_objects.rb
394
413
  - examples/quickstart/README.md
395
414
  - examples/quickstart/app/actors/ticket_sale.rb
396
415
  - examples/quickstart/smoke.rb