Interface NotificationAwareDependency

All Superinterfaces:
LogOutputAppendable, NotificationQueue.Dependency
All Known Implementing Classes:
DynamicWhereFilter

public interface NotificationAwareDependency extends NotificationQueue.Dependency
A NotificationQueue.Dependency that changes its state in place, keeping no previous version, so a snapshot using previous values cannot read it consistently across such a change.

An operation reads that state inside a snapshot attempt that may fail, so it subscribes only when that attempt commits, and only if the state has not changed since the attempt began. That is the atomic check-and-subscribe a source table offers through addUpdateListener, so an unsubscribed dependency never has a result to notify.

This deliberately does not extend NotificationStepSource, whose step means "finished dispatching" and lets OperationSnapshotControlEx treat a dependency as satisfied without asking. This interface reports the opposite, that a change has begun, so conflating the two would let a snapshot read state that is still being rewritten. Completion is reported through NotificationQueue.Dependency.satisfied(long) as usual.

  • Method Details

    • lastStateChangeStep

      long lastStateChangeStep()
      The step on which this dependency last began changing the state it guards, or NotificationStepReceiver.NULL_NOTIFICATION_STEP if it never has.

      Record the step in a volatile field before changing that state, never after: a reader that observed the change must see the new step when it checks, or it will accept a torn read as consistent. Do not record a step for a notification that leaves the guarded state unchanged.

      Returns:
      The step on which the guarded state last began changing
    • subscribe

      boolean subscribe(long requiredLastStateChangeStep)
      Start delivering state changes to the operation whose snapshot attempt is committing. The check and the subscription are one atomic step, taken against the same guard the state changes take, so a change either reaches that operation or is the reason it is refused.
      Parameters:
      requiredLastStateChangeStep - The lastStateChangeStep() read when the attempt began
      Returns:
      Whether the operation was subscribed
      Throws:
      RuntimeException - If this dependency has failed, so no attempt over it can ever commit
    • unsubscribe

      void unsubscribe()
      Stop delivering state changes, for an attempt rejected after this dependency accepted it.