-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: emit transaction lifecycle events #244
Conversation
ae5e1ed
to
764182c
Compare
8a67960
to
356af0f
Compare
0ef292b
to
79bd1f5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left my thoughts. Looks good.
@@ -416,6 +419,7 @@ def commit_transaction(self, ledger_transaction, fulfillment_identifier=None, ex | |||
ledger_transaction.external_reference.set([external_reference]) | |||
ledger_transaction.state = TransactionStateChoices.COMMITTED | |||
ledger_transaction.save() | |||
event_bus.send_transaction_committed_event(ledger_transaction) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the event bus send fails for these calls is the ledger_transaction
also rolled back?
I think my overall question is this: When these event emissions fail to send, should the related DB writes also fail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because then we're making the communication pattern synchronous instead of asynchronous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But if the event doesn't make it on to the bus, and the record is written, systems downstream of this message will not be able to act accordingly. Not having this event hit the bus means that whatever actions were supposed to happen because of this do not happen leaving the system in an inconsistent state.
I don't believe this makes it synchronous. It's more that the transaction isn't complete until the event is sent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also suggest that this does not make it synchronous either as we are simply writing that the event happened. Not waiting for downstream systems to execute on the message.
I think that writing these messages on to the bus and ensuring that call succeeds is just as important now as ensuring the DB record is written.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Synchronous was the wrong word, it's more like you'd be making the send of the message part of the "atomic block" of the flow.
Part of the goal of using an async event broker, though, is to move toward "eventual consistency", and force our services to adapt to inconsistent states. The ideal thing to do if kafka is down/unreachable/whatever isn't to fail the redemption flow; it's to have a mechanism for replaying events that occurred in a given time window, and to be able to rely on idempotent consumers to process those replayed events. Or to implement a dead-letter queue (here on the producer side).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now, having said all that, I should go through and check if this is already called from within a transaction.atomic()
block.
b302093
to
9bfea23
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
The one thing I'm confused about is the purpose of event_key_field. I have no idea how it works...what dictionary has "ledger_transaction" as a top-level key? Why is the UUID of a transaction considered unique enough for an event? What happens when two events about the same transaction are emitted...wouldn't they conflict? The openedx-events documentation uses similarly confusing keys to me, so I know there's something I don't understand about this, and it's net-new anyway, so I don't want to block.
@pwnage101 The signal's data is what maps a |
Emit openedx events (to the event bus) when transactions are created, committed, failed, and reversed. Additionally fixes a bug in the write-reversals mgmt command that proceeded to write a reversal in case an external fulfillment could not successfully be canceled. ENT-8761 ENT-9009
9bfea23
to
022ed99
Compare
Emit openedx events (to the event bus) when transactions are created, committed, failed, and reversed.
Additionally fixes a bug in the write-reversals mgmt command that proceeded to write a reversal in case an external fulfillment could not successfully be canceled.
ENT-8761
ENT-9009
See proposed consumption: openedx/enterprise-access#502
Testing instructions
make app-logs
in enterprise-subsidy, or have the local kafka control center running in your browser.Example of reversal signal being sent
From enterprise-subsidy:
In local confluent:
The event data:
Merge checklist