aaronmallen/activeinteractor

[Question] What is the expected Rollback behavior with complex skip_rollback ?

aka-momo opened this issue ยท 6 comments

Question

Interactors-Page-1 (1)

I'm trying to understand the correct behavior for rollback cycle when a skip_rollback option is set to true on TinyOrganizer, while the It did not complete execution.

In other words, Does skip_rollback mean we skip rollback for a subtree which is fully called? What happens when the failure occures inside TinyOrganizer itself?

Note: This question is mainly to understand the edge cases of rollback cycle to consider in future releases

My Initial guessing of rollback steps will be

  1. Interactor6
  2. Interactor5
  3. TinyOrganizer
  4. Interactor4
  5. SmallOrganizer
  6. Interactor2
  7. Interactor1
  8. BigOrganizer

In case this is the correct behavior.

We are currently introducing in #291 which highlights 3 types of failures:

  1. Input Validation Error (Occurs before perform)
  2. context.fail! (Happen during perform or callbacks)
  3. Output Validation Error (Occurs after perform)

Do we need to rollback Interactor6 for specific cases?

๐Ÿค” The skip_rollback options wasn't really built with organizers in mind... ideally an organizer would ignore this option all together and let it's organized interactors inform it if they should or should not be rolled back. That being said I don't believe organizers currently ignore this option which I would consider a bug.

๐Ÿค” The skip_rollback options wasn't really built with organizers in mind... ideally an organizer would ignore this option all together and let it's organized interactors inform it if they should or should not be rolled back. That being said I don't believe organizers currently ignore this option which I would consider a bug.

Makes sense ๐Ÿ‘ I totally agree it rather be disabled for Organizers.

Ignoring skip_callback for organizers!

#291 suggests that we will not self rollback an interactor for failing before being performed

  1. Input Validation Error (Occurs before perform)

But it is rolledback for

  1. context.fail! (Happen during perform or callbacks)
  2. Output Validation Error (Occurs after perform)

I was thinking if some interactor decides to call fail! inside perform. Is there a real example where that should trigger a rollback to self. WDYT @aaronmallen ?

Trivial Use case

def perform
  context.some_object = SomeObject.new

  context.fail!('some error') unless context.some_object.save
end

def rollback
  context.some_object.destroy
end

@mohameddiaa27 I've actually thought about this quite a bit, so the input context object and the output context object are never mutated, they're just copies of input we've received in the form of hash, and output we've received in the form of perform. This means all the mutations happen on the run time context. We'll want to maintain this object to the very end of the cycle I think as it is the context we should use to perform rollback... obviously if we invalidate the input object we never made it to the perform cycle so there shouldn't be anything to rollback.

Thank you that answers my question ๐Ÿ™