Compensazione del workflow
La compensazione consente di associare un gestore di rollback a un passaggio completato del workflow. Queuety memorizza uno snapshot dello stato pubblico al termine del passaggio, quindi esegue i gestori di compensazione in ordine inverso quando il workflow viene annullato o, facoltativamente, quando non riesce.
Il metodo compensate_with()
Chiamate compensate_with() subito dopo il passaggio che deve annullare:
use Queuety\Queuety;
Queuety::workflow( 'provision_account' )
->then( CreateRemoteUserStep::class )
->compensate_with( DeleteRemoteUserCompensation::class )
->then( CreateSubscriptionStep::class )
->compensate_with( CancelSubscriptionCompensation::class )
->then( SendWelcomeEmailStep::class )
->dispatch( [ 'user_id' => 42 ] );
Se il workflow viene annullato in seguito, viene eseguito Queuety:
CancelSubscriptionCompensationDeleteRemoteUserCompensation
Gestori di compensazione
I gestori di compensazione implementano Contracts\Compensation:
use Queuety\Contracts\Compensation;
final class DeleteRemoteUserCompensation implements Compensation {
public function handle( array $state ): void {
remote_api_delete_user( $state['remote_user_id'] );
}
}
Il gestore riceve lo stato pubblico del workflow così com'era subito dopo il completamento del passaggio compensato. Le chiavi interne riservate non sono incluse.
Annullamento o errore
In caso di annullamento esplicito, le compensazioni dei passaggi completati vengono sempre eseguite prima del gestore facoltativo on_cancel().
In caso di errore, le compensazioni vengono eseguite solo se le attivate esplicitamente:
Queuety::workflow( 'provision_account' )
->then( CreateRemoteUserStep::class )
->compensate_with( DeleteRemoteUserCompensation::class )
->then( CreateSubscriptionStep::class )
->compensate_with( CancelSubscriptionCompensation::class )
->then( ChargeCardStep::class )
->compensate_on_failure()
->dispatch( $payload );
Senza compensate_on_failure(), un workflow non riuscito conserva intatta la cronologia dei passaggi completati ed è possibile riprovare dal passaggio non riuscito.
Con compensate_on_failure(), le compensazioni dei passaggi completati vengono eseguite dopo che il workflow è contrassegnato come non riuscito. In seguito, retry_workflow() genera un'eccezione perché il workflow è già stato compensato.
Tipi di passaggio supportati
È possibile associare la compensazione a:
- passaggi sequenziali
then() - gruppi
parallel() - passaggi
for_each() - passaggi
run_workflow() - passaggi di attesa
delay() - passaggi di segnale
wait_for_signal() - passaggi di dipendenza del workflow
wait_for_workflow()
Per run_workflow() e for_each(), lo snapshot di compensazione viene registrato dopo che il lavoro annidato o ramificato è terminato del tutto.
on_cancel() e compensazione
Usate compensate_with() per annullare in ordine inverso gli effetti collaterali dei passaggi completati.
Usate on_cancel() per un singolo hook di pulizia a livello di workflow, da eseguire ogni volta che il workflow viene annullato esplicitamente.