Skip to content

Instantly share code, notes, and snippets.

@bdewater
Last active October 26, 2024 02:12
Show Gist options
  • Save bdewater/3e6f04c7dc8144f5814b680ce3b7771a to your computer and use it in GitHub Desktop.
Save bdewater/3e6f04c7dc8144f5814b680ce3b7771a to your computer and use it in GitHub Desktop.
Job with resumable steps
# frozen_string_literal: true
class SubmitWidgetJob < ApplicationJob
include JobIteration::Iteration
queue_as :default
attr_accessor :funding_token, :confirmation_number, :profile_id
STEPS = [
"tokenize_card",
"make_payment",
"create_profile",
"change_billing_account",
"schedule_payments",
"submit_widget",
].freeze
def build_enumerator(widget, cursor:)
drop = if cursor.nil?
0
else
index = steps.index(cursor)
index ? index + 1 : raise(ArgumentError, "Invalid cursor: #{cursor}")
end
STEPS.map { [_1, _1] }.drop(drop).to_enum { steps.size - drop }
end
def each_iteration(current_step, widget)
case current_step
when "tokenize_card"
tokenize_card(widget)
when "make_payment"
make_payment(widget)
when "create_profile"
create_profile(widget)
when "change_billing_account"
change_billing_account(widget)
when "schedule_payments"
schedule_payments(widget)
when "submit_widget"
submit_widget(widget)
end
end
# These two methods are public Active Job API, extended by JobIteration, and here we extend them further
# https://api.rubyonrails.org/classes/ActiveJob/Core.html#method-i-serialize
def serialize
super.merge(
"funding_token" => funding_token,
"confirmation_number" => confirmation_number,
"profile_id" => profile_id,
)
end
def deserialize(job_data)
super
self.funding_token = job_data["funding_token"]
self.confirmation_number = job_data["confirmation_number"]
self.profile_id = job_data["profile_id"]
end
private
def tokenize_card(widget)
self.funding_token = SecureRandom.hex(16)
puts "Step 1 sets funding_token to #{funding_token}"
sleep(1)
end
def make_payment(widget)
self.confirmation_number = SecureRandom.random_number(10)
puts "Step 2 sets confirmation_number to #{confirmation_number}"
sleep(1)
end
def create_profile(widget)
self.profile_id = SecureRandom.random_number(1000)
puts "Step 3 sets profile_id to #{profile_id}"
sleep(1)
end
def change_billing_account(widget)
puts "Step 4 uses #{funding_token}, #{profile_id}"
sleep(1)
end
def schedule_payments(widget)
puts "Step 5 uses #{funding_token}, #{profile_id}"
sleep(1)
end
def submit_widget(widget)
puts "Step 6 uses #{confirmation_number} - done!"
sleep(1)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment