lib/templates/mongoid_outbox.rb in outboxable-1.0.0 vs lib/templates/mongoid_outbox.rb in outboxable-1.0.2

- old
+ new

@@ -1,38 +1,38 @@ class Outbox include Mongoid::Document include Mongoid::Timestamps - include SimpleEnum::Mongoid - attr_accessor :allow_publish + attr_writer :allow_publish # Fields field :status, type: String, default: 'pending' - field :size, type: String, default: 'single' + field :size, type: String, default: 'single' field :exchange, type: String, default: '' field :routing_key, type: String, default: '' field :attempts, type: Integer, default: 0 field :last_attempted_at, type: DateTime, default: nil field :retry_at, type: DateTime, default: nil + field :idempotency_key, type: String + field :payload, type: Hash, default: {} field :headers, type: Hash, default: {} + index({ idempotency_key: 1 }, { unique: true, name: 'idempotency_key_unique_index' }) + before_save :check_publishing + before_create :set_idempotency_key # Callbacks before_create :set_last_attempted_at - after_commit :publish, if: :allow_publish? + after_save :publish, if: :allow_publish - # Enums - as_enum :status, { pending: 0, processing: 1, published: 2, failed: 3 }, pluralize_scopes: false, map: :string - as_enum :size, { single: 0, batch: 1 }, pluralize_scopes: false, map: :string - # Validations validates :payload, :exchange, :routing_key, presence: true # Associations belongs_to :outboxable, polymorphic: true, optional: true @@ -40,17 +40,32 @@ def set_last_attempted_at self.last_attempted_at = 10.seconds.from_now end def publish - Outboxable::Worker.perform_async(id) + Outboxable::Worker.perform_async(idempotency_key) update(status: :processing, last_attempted_at: 1.minute.from_now, allow_publish: false) end + def set_idempotency_key + self.idempotency_key = SecureRandom.uuid if idempotency_key.blank? + end + def check_publishing self.allow_publish = false if published? end def allow_publish - @allow_publish || true + return true if @allow_publish.nil? + + @allow_publish + end + + %w[pending processing published failed].each do |status| + define_method "#{status}?" do + self.status == status + end + + # define scope + scope status, -> { where(status:) } end end