Skip to content

Fix OutboxJoin schema initialization and InMemoryLease concurrency issues in fanout tests - #99

Merged
SamuelMcAravey merged 2 commits into
codex/2025-12-19-add-integration-tests-for-fanoutcoordinatorfrom
copilot/sub-pr-98
Dec 19, 2025
Merged

Fix OutboxJoin schema initialization and InMemoryLease concurrency issues in fanout tests#99
SamuelMcAravey merged 2 commits into
codex/2025-12-19-add-integration-tests-for-fanoutcoordinatorfrom
copilot/sub-pr-98

Conversation

Copilot AI commented Dec 19, 2025

Copy link
Copy Markdown
Contributor

FanoutCoordinatorIntegrationTests failed with "Invalid object name 'dbo.OutboxJoin'" and had concurrency issues in the test lease implementation.

Changes

  • Schema initialization: Added missing EnsureOutboxJoinSchemaAsync call to create OutboxJoin/OutboxJoinMember tables
  • Lease acquisition race condition: Replaced check-then-act with atomic AddOrUpdate pattern
  • FencingToken thread safety: Changed to Interlocked operations for increment/read
  • Background task lifecycle: Tracked expiration task and properly awaited during disposal
  • Test data consistency: Fixed workKey mismatch ("daily" → "default") in cursor advancement test
// Before: race condition between check and insert
while (leases.TryGetValue(resourceName, out var existing)) {
    if (existing.IsExpired) leases.TryRemove(resourceName, out _);
    else return null;
}
leases[resourceName] = lease;  // Can overwrite another thread's lease

// After: atomic operation
var resultingLease = leases.AddOrUpdate(
    resourceName,
    _ => newLease,
    (_, existing) => existing.IsExpired ? newLease : existing);

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: SamuelMcAravey <11021165+SamuelMcAravey@users.noreply.github.com>
Copilot AI changed the title [WIP] Add fanout coordinator integration coverage Fix OutboxJoin schema initialization and InMemoryLease concurrency issues in fanout tests Dec 19, 2025
Copilot AI requested a review from SamuelMcAravey December 19, 2025 06:25
@SamuelMcAravey
SamuelMcAravey marked this pull request as ready for review December 19, 2025 06:25
@SamuelMcAravey
SamuelMcAravey merged commit a6e4473 into codex/2025-12-19-add-integration-tests-for-fanoutcoordinator Dec 19, 2025
@SamuelMcAravey
SamuelMcAravey deleted the copilot/sub-pr-98 branch December 19, 2025 06:25

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +310 to 314
if (!resultingLease.IsExpired)
{
// Another thread holds a non-expired lease.
newLease.DisposeAsync().AsTask().Wait();
return Task.FromResult<ISystemLease?>(null);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid clearing active lease when acquisition is blocked

When a non-expired lease already exists, AddOrUpdate returns it and we immediately dispose the freshly created newLease (lines 310-313). DisposeAsync always invokes RemoveLease, so this path removes the currently held lease from the dictionary even though we return null, letting a subsequent caller acquire a second lease while the original holder is still active. Any concurrent acquisition attempt against an active lease can therefore break exclusivity and allow multiple coordinators to run simultaneously.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants