T1: tests stop sharing state they don't own
- JobQueue takes an optional scope, so a test's worker leases and reaps only its own jobs. - The dead-host delivery test runs alone (Exclusive), on its own jobs, and cleans up the breaker rows it trips; the breaker has tests of its own on unique hosts. - Index and migration tests run alone: they drop indexes and rewrite every post. - DomainBlocks.Load replaces reflection and a database-wide block in tests. - Harness.Outgoing sees only deliveries queued since the harness started: Peer ports are reused within a run, which made the circle test flaky. - Two pure-logic tests leave Mongo-gated classes, so CI runs them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ELjqpznMFMNrJoJUj6K5p2
This commit is contained in:
1 parent
7c6fe80f1b
commit
00b2685cf4
14 files changed
+285
-106
No files matched your search
@@ -44,9 +44,11 @@ namespace PrivaPub.Federation.Moderation
|
||||
|
||||
public bool IsSuspended(string host) => Find(host)?.Severity == DomainBlockSeverity.Suspend;
|
||||
|
||||
public async Task Reload(CancellationToken token)
|
||||
public async Task Reload(CancellationToken token) =>
|
||||
Load(await DB.Default.Find<DomainBlock>().ExecuteAsync(token));
|
||||
|
||||
public void Load(IEnumerable<DomainBlock> blocks)
|
||||
{
|
||||
var blocks = await DB.Default.Find<DomainBlock>().ExecuteAsync(token);
|
||||
_blocks = blocks.Where(b => !string.IsNullOrEmpty(b.Domain))
|
||||
.GroupBy(b => Normalise(b.Domain))
|
||||
.ToDictionary(g => g.Key, g => g.First());
|
||||
|
||||
@@ -4,6 +4,7 @@ using MongoDB.Entities;
|
||||
using PrivaPub.Models.Jobs;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace PrivaPub.Infrastructure.Jobs
|
||||
{
|
||||
@@ -39,6 +40,13 @@ namespace PrivaPub.Infrastructure.Jobs
|
||||
|
||||
readonly string _owner = $"{Environment.MachineName}:{Environment.ProcessId}";
|
||||
readonly ConcurrentDictionary<JobKind, SemaphoreSlim> _signals = new();
|
||||
readonly FilterDefinition<Job> _scope = Builders<Job>.Filter.Empty;
|
||||
|
||||
public JobQueue()
|
||||
{
|
||||
}
|
||||
|
||||
public JobQueue(Expression<Func<Job, bool>> scope) => _scope = Builders<Job>.Filter.Where(scope);
|
||||
|
||||
public async Task<bool> Enqueue(JobKind kind, string payload, string host, string dedupeKey, CancellationToken token) =>
|
||||
await EnqueueMany(new[] { new Job { Kind = kind, Payload = payload, Host = host, DedupeKey = dedupeKey } }, token) == 1;
|
||||
@@ -66,7 +74,7 @@ namespace PrivaPub.Infrastructure.Jobs
|
||||
var now = DateTime.UtcNow;
|
||||
var busy = busyHosts?.ToList() ?? new List<string>();
|
||||
return await DB.Default.UpdateAndGet<Job>()
|
||||
.Match(j => j.Kind == kind && j.State == JobState.Pending && j.RunAt <= now && !busy.Contains(j.Host))
|
||||
.Match(f => f.Where(j => j.Kind == kind && j.State == JobState.Pending && j.RunAt <= now && !busy.Contains(j.Host)) & _scope)
|
||||
.Modify(j => j.State, JobState.Running)
|
||||
.Modify(j => j.LeasedUntil, now + LeaseTime)
|
||||
.Modify(j => j.LeaseOwner, _owner)
|
||||
@@ -106,7 +114,7 @@ namespace PrivaPub.Infrastructure.Jobs
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
var result = await DB.Default.Update<Job>()
|
||||
.Match(j => j.State == JobState.Running && j.LeasedUntil < now)
|
||||
.Match(f => f.Where(j => j.State == JobState.Running && j.LeasedUntil < now) & _scope)
|
||||
.Modify(j => j.State, JobState.Pending)
|
||||
.Modify(j => j.RunAt, now)
|
||||
.Modify(j => j.LeasedUntil, null)
|
||||
|
||||
Reference in new issue
Block a user