Skip to content

intent: the settlement create and updated handlers race on the payload amount - a delayed create event can transiently release fresh allocations #6865

Description

@delchev

Since #6846 both settlement handlers - <Name>OnPayment (create topic) and <Name>OnPaymentUpdated (-updated topic) - contain the release branch, and both trust the AMOUNT carried in the message payload rather than re-reading the store.

The two handlers are subscribers on two different topics with no cross-topic ordering guarantee, so:

  1. payment created at 100 - create event published;
  2. quick upward correction to 150 - -updated published;
  3. OnPaymentUpdated delivers first and allocates 150;
  4. the DELAYED create event (payload pot = 100) computes pot - allocated = -50 and releases 50 - the payment sits under-allocated until the next payment event re-converges it.

Milliseconds-scale window and self-healing, but new with #6846: before it, the create-only handler was floored at zero (.max(BigDecimal.ZERO)) and could never shrink allocations.

The Rollup template is deliberately stale-proof by recomputing from the store; the settlement parses the payload because a cross-model payment is a projection with no local repository to re-read. Options that keep that constraint:

  • re-read the payment through its repository when the payment is LOCAL (the common case), keeping the payload only for cross-model sources;
  • make the create handler allocation-only again (never release) - a create event can only ever be the FIRST word about a payment, so it has nothing to release that it should;
  • both: the second is a one-line floor restore and closes the race outright, the first improves the updated handler's accuracy too.

Follow-up to #6846.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions