Support Happens-Before Constraints in Spec.AllowsConcurrent - #31
Merged
Conversation
Contributor
Author
|
@microsoft-github-policy-service agree |
imnaseer
reviewed
Jul 21, 2026
imnaseer
reviewed
Jul 22, 2026
imnaseer
reviewed
Jul 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add happens-before constraints to
Spec.AllowsConcurrentfor linearizability checkingProblem
Spec.AllowsConcurrentvalidates a group of concurrent operation calls by searching for some sequential ordering that explains the observed responses. This supports sequential consistency, but not full linearizability.Linearizability additionally requires preserving real-time (wall-clock) precedence: when one operation completes before another begins, the first must appear before the second in the linearization. Today,
AllowsConcurrenttreats all operations as mutually concurrent and freely reorders them, so it cannot distinguish a valid linearization from one that violates real-time ordering.Solution
Extend
Spec.AllowsConcurrentwith an optionalhappensBeforeparameter:Each edge
(before, after)constrains the search to orderings where the call at indexbeforeappears before the call at indexafter. Operations without a happens-before relationship are still reordered freely.Callers derive edges from wall-clock timing: whenever one call completes before another starts, add a happens-before edge. Overlapping calls remain unordered. The resulting partial order (a DAG) models any concurrent history.
This is additive and backward-compatible — the existing two-parameter overload delegates to the new one with an empty edge set.
How it works
ContractStepFunctionalready participates in Accordant's state-graph exploration. Each step function can be enabled or disabled depending on the current state. This PR adds a predecessor gate: a step function with happens-before predecessors is disabled until all predecessor step IDs appear in the current linearization path.The path is built by
StateGraph.ExploreStateGraphas it traverses orderings. When a step function'sApplyInternalsees that its predecessors haven't all run yet, it returnsnull(disabled), pruning that branch of the search.Files changed
Accordant/StepFunction/ContractStepFunction.cs_predecessorIdsfield,SetPredecessorIds(), and applies predecessor gate inApplyInternal(IState, path)Accordant.Operations/Operation/Spec.csAllowsConcurrentoverload with edge validation and predecessor wiringTests/Accordant.Operations.Tests/OperationTests.csTests
PrunesInvalidOrderingsRedundantEdgeDoesNotChangeResultTransitiveChainMultiplePredecessorsSelfLoopThrowsArgumentExceptionOutOfRangeIndexThrowsArgumentException