Registry phase 2 migration: Container repository state machine
Context
The context for this issue can be viewed in the epic &7316 (closed) and the breakdown of work can be viewed in this comment &7316 (comment 792633854).
🤖 State Machine
We have many states/transitions to handle here. I think it would be beneficial to use the already included https://github.com/state-machines/state_machines-activerecord gem to manage this part.
Roughly speaking here, this is what we could have (code might be inaccurate):
state_machine :migration_state, initial_state: :default do
event :start_pre_import do
transition default: :pre_importing
end
event :finish_pre_import do
transition pre_importing: :pre_import_done
end
event :start_import do
transition pre_import_done: :importing
end
event :finish_import do
transition importing: :done
end
event :already_migrated do
transition default: :done
end
event :abort do
transition %i[pre_importing importing] => :aborted
end
event :skip do
transition %i[default pre_importing importing] => :skipped
end
event :retry_pre_import do
transition aborted: :pre_importing
end
event :retry_import do
transition aborted: :importing
end
before_transition any => :pre_importing do |container_repository|
container_repository.migration_pre_import_started_at = Time.zone.now
container_repository.client.start_pre_import # this can make the transition fail
end
before_transition pre_importing: :pre_import_done do |container_repository|
container_repository.migration_pre_import_done_at = Time.zone.now
end
before_transition any => :importing do |container_repository|
container_repository.migration_import_started_at = Time.zone.now
container_repository.client.start_import # this can make the transition fail
end
before_transition importing: :done do |container_repository|
container_repository.migration_import_done_at = Time.zone.now
end
before_transition any => :aborted do |container_repository|
container_repository.migration_aborted_in_state = container_repository.migration_state
container_repository.migration_retries_count += 1
end
before_transition any => %i[done aborted] do
EnqueuerJob.enqueue # perform_async or perform_in depending on the speed FF
end
end
This should upgrade the container repository with all the necessary scopes/methods to handle the evolution of the migration state.
I'm not sure if all these before_transition
blocks are implementable like this. For example, can we do an http request during a before_transition
? I left this to a side as an implementation detail.