[backend/federation] Filter skipped & blocked instances in PreDeliverQueue (ISH-366)
This: - improves performance (because we can check them in batches) - improves efficiency (because we don't create deliver jobs that get discarded immediately) - allows us to check whether the activity is an ASFollow & let it through if it is (for skipped instances filter only) We still check for blocked instances in the deliver queue in case a deliver job is created via another code path.
This commit is contained in:
parent
aed143cc59
commit
9dbc7cfc14
3 changed files with 63 additions and 43 deletions
|
@ -37,12 +37,4 @@ public class FederationControlService(
|
|||
return await db.BlockedInstances.AnyAsync(p => finalHosts.Any(host => host == p.Host ||
|
||||
host.EndsWith("." + p.Host)));
|
||||
}
|
||||
|
||||
public async Task<bool> ShouldSkipAsync(string host)
|
||||
{
|
||||
return await db.Instances.AnyAsync(p => p.Host == host.ToLowerInvariant() &&
|
||||
((p.IsNotResponding &&
|
||||
p.LastCommunicatedAt < DateTime.UtcNow - TimeSpan.FromDays(7)) ||
|
||||
p.IsSuspended));
|
||||
}
|
||||
}
|
|
@ -29,12 +29,6 @@ public class DeliverQueue(int parallelism)
|
|||
return;
|
||||
}
|
||||
|
||||
if (await fedCtrl.ShouldSkipAsync(jobData.RecipientHost))
|
||||
{
|
||||
logger.LogDebug("fedCtrl.ShouldSkipAsync returned true, skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogDebug("Delivering activity to: {uri}", jobData.InboxUrl);
|
||||
|
||||
var key = await cache.FetchAsync($"userPrivateKey:{jobData.UserId}", TimeSpan.FromMinutes(60), async () =>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq.Expressions;
|
||||
using Iceshrimp.Backend.Core.Configuration;
|
||||
using Iceshrimp.Backend.Core.Database;
|
||||
using Iceshrimp.Backend.Core.Database.Tables;
|
||||
|
@ -61,6 +62,8 @@ public class PreDeliverQueue(int parallelism)
|
|||
|
||||
var inboxQueryResults = await query.Where(p => p.InboxUrl != null && p.Host != null)
|
||||
.Distinct()
|
||||
.SkipDeadInstances(activity, db)
|
||||
.SkipBlockedInstances(config.Value.FederationMode, db)
|
||||
.ToListAsync(token);
|
||||
|
||||
if (inboxQueryResults.Count == 0) return;
|
||||
|
@ -91,43 +94,74 @@ public class PreDeliverQueue(int parallelism)
|
|||
UserId = jobData.ActorId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private class InboxQueryResult : IEquatable<InboxQueryResult>
|
||||
file class InboxQueryResult : IEquatable<InboxQueryResult>
|
||||
{
|
||||
public required string? Host;
|
||||
public required string? InboxUrl;
|
||||
|
||||
public bool Equals(InboxQueryResult? other)
|
||||
{
|
||||
public required string? Host;
|
||||
public required string? InboxUrl;
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
return InboxUrl == other.InboxUrl && Host == other.Host;
|
||||
}
|
||||
|
||||
public bool Equals(InboxQueryResult? other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
return InboxUrl == other.InboxUrl && Host == other.Host;
|
||||
}
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != GetType()) return false;
|
||||
return Equals((InboxQueryResult)obj);
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != GetType()) return false;
|
||||
return Equals((InboxQueryResult)obj);
|
||||
}
|
||||
[SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode", Justification =
|
||||
"We are using this as a Tuple that works with LINQ on our IQueryable iterator. This is therefore intended behavior.")]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(InboxUrl, Host);
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode", Justification =
|
||||
"We are using this as a Tuple that works with LINQ on our IQueryable iterator. This is therefore intended behavior.")]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(InboxUrl, Host);
|
||||
}
|
||||
public static bool operator ==(InboxQueryResult? left, InboxQueryResult? right)
|
||||
{
|
||||
return Equals(left, right);
|
||||
}
|
||||
|
||||
public static bool operator ==(InboxQueryResult? left, InboxQueryResult? right)
|
||||
{
|
||||
return Equals(left, right);
|
||||
}
|
||||
public static bool operator !=(InboxQueryResult? left, InboxQueryResult? right)
|
||||
{
|
||||
return !Equals(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool operator !=(InboxQueryResult? left, InboxQueryResult? right)
|
||||
file static class QueryableExtensions
|
||||
{
|
||||
public static IQueryable<InboxQueryResult> SkipDeadInstances(
|
||||
this IQueryable<InboxQueryResult> query, ASActivity activity, DatabaseContext db
|
||||
)
|
||||
{
|
||||
if (activity is ASFollow) return query;
|
||||
return query.Where(user => !db.Instances.Any(p => p.Host == user.Host &&
|
||||
((p.IsNotResponding &&
|
||||
p.LastCommunicatedAt <
|
||||
DateTime.UtcNow - TimeSpan.FromDays(7)) ||
|
||||
p.IsSuspended)));
|
||||
}
|
||||
|
||||
public static IQueryable<InboxQueryResult> SkipBlockedInstances(
|
||||
this IQueryable<InboxQueryResult> query, Enums.FederationMode mode, DatabaseContext db
|
||||
)
|
||||
{
|
||||
Expression<Func<InboxQueryResult, bool>> expr = mode switch
|
||||
{
|
||||
return !Equals(left, right);
|
||||
}
|
||||
Enums.FederationMode.BlockList => u =>
|
||||
u.Host == null || !db.BlockedInstances.Any(p => u.Host == p.Host || u.Host.EndsWith("." + p.Host)),
|
||||
Enums.FederationMode.AllowList => u =>
|
||||
u.Host == null || db.AllowedInstances.Any(p => u.Host == p.Host || u.Host.EndsWith("." + p.Host)),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(mode), mode, null)
|
||||
};
|
||||
|
||||
return query.Where(expr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue