This commit is contained in:
2025-09-13 20:08:52 +02:00
parent 693d3c6af7
commit 6852869313
2 changed files with 54 additions and 12 deletions

View File

@@ -57,22 +57,26 @@ public sealed class InMemoryPresenceStore : IDiscoveryPresenceStore
} }
public (bool Found, string? Token, string TargetUid, string? DisplayName) TryMatchAndIssueToken(string requesterUid, string hash) public (bool Found, string? Token, string TargetUid, string? DisplayName) TryMatchAndIssueToken(string requesterUid, string hash)
{
if (_presence.TryGetValue(hash, out var entry))
{ {
if (_presence.TryGetValue(hash, out var entry)) // Refresh TTL for this presence whenever it is matched (regardless of AllowRequests)
{ var refreshed = (entry.Uid, DateTimeOffset.UtcNow.Add(_presenceTtl), entry.DisplayName, entry.AllowRequests);
if (string.Equals(entry.Uid, requesterUid, StringComparison.Ordinal)) _presence[hash] = refreshed;
return (false, null, string.Empty, null);
// Visible but requests disabled → no token if (string.Equals(entry.Uid, requesterUid, StringComparison.Ordinal))
if (!entry.AllowRequests) return (false, null, string.Empty, null);
return (true, null, entry.Uid, entry.DisplayName);
var token = Guid.NewGuid().ToString("N"); // Visible but requests disabled → no token
_tokens[token] = (entry.Uid, DateTimeOffset.UtcNow.Add(_tokenTtl)); if (!entry.AllowRequests)
return (true, token, entry.Uid, entry.DisplayName); return (true, null, entry.Uid, entry.DisplayName);
}
return (false, null, string.Empty, null); var token = Guid.NewGuid().ToString("N");
_tokens[token] = (entry.Uid, DateTimeOffset.UtcNow.Add(_tokenTtl));
return (true, token, entry.Uid, entry.DisplayName);
} }
return (false, null, string.Empty, null);
}
public bool ValidateToken(string token, out string targetUid) public bool ValidateToken(string token, out string targetUid)
{ {
@@ -82,6 +86,18 @@ public (bool Found, string? Token, string TargetUid, string? DisplayName) TryMat
if (info.ExpiresAt > DateTimeOffset.UtcNow) if (info.ExpiresAt > DateTimeOffset.UtcNow)
{ {
targetUid = info.TargetUid; targetUid = info.TargetUid;
// Optional robustness: refresh TTL for all presence entries of this target
var newExp = DateTimeOffset.UtcNow.Add(_presenceTtl);
foreach (var kv in _presence.ToArray())
{
if (string.Equals(kv.Value.Uid, targetUid, StringComparison.Ordinal))
{
var v = kv.Value;
_presence[kv.Key] = (v.Uid, newExp, v.DisplayName, v.AllowRequests);
}
}
return true; return true;
} }
_tokens.TryRemove(token, out _); _tokens.TryRemove(token, out _);

View File

@@ -100,6 +100,10 @@ public sealed class RedisPresenceStore : IDiscoveryPresenceStore
if (p == null || string.IsNullOrEmpty(p.Uid)) return (false, null, string.Empty, null); if (p == null || string.IsNullOrEmpty(p.Uid)) return (false, null, string.Empty, null);
if (string.Equals(p.Uid, requesterUid, StringComparison.Ordinal)) return (false, null, string.Empty, null); if (string.Equals(p.Uid, requesterUid, StringComparison.Ordinal)) return (false, null, string.Empty, null);
// Refresh TTLs for this presence whenever it is matched
_db.KeyExpire(KeyForHash(hash), _presenceTtl);
_db.KeyExpire(KeyForUidSet(p.Uid), _presenceTtl);
// Visible but requests disabled → return without token // Visible but requests disabled → return without token
if (!p.AllowRequests) if (!p.AllowRequests)
{ {
@@ -123,6 +127,28 @@ public sealed class RedisPresenceStore : IDiscoveryPresenceStore
var val = _db.StringGet(key); var val = _db.StringGet(key);
if (!val.HasValue) return false; if (!val.HasValue) return false;
targetUid = val!; targetUid = val!;
try
{
var setKey = KeyForUidSet(targetUid);
var members = _db.SetMembers(setKey);
if (members is { Length: > 0 })
{
var batch = _db.CreateBatch();
foreach (var m in members)
{
var h = (string)m;
batch.KeyExpireAsync(KeyForHash(h), _presenceTtl);
}
batch.KeyExpireAsync(setKey, _presenceTtl);
batch.Execute();
}
else
{
// Still try to extend the set TTL even if empty
_db.KeyExpire(setKey, _presenceTtl);
}
}
catch { /* ignore TTL refresh issues */ }
return true; return true;
} }