feat: add reverse response mapping for cross-account request-reply (Gap 9.9)
This commit is contained in:
@@ -737,6 +737,46 @@ public sealed class Account : IDisposable
|
||||
return new AccountClaimUpdateResult(Changed: false, ChangedFields: [], UpdateCount: Volatile.Read(ref _claimUpdateCount));
|
||||
}
|
||||
|
||||
// Reverse response map for cross-account request-reply routing.
|
||||
// When a service import rewrites the reply subject, a reverse mapping is stored so that
|
||||
// when the response arrives it can be forwarded back to the original requester's account.
|
||||
// Go reference: server/accounts.go — addRespMapEntry / checkForReverseEntries.
|
||||
private readonly ConcurrentDictionary<string, ReverseResponseMapEntry> _reverseResponseMap =
|
||||
new(StringComparer.Ordinal);
|
||||
|
||||
/// <summary>
|
||||
/// Adds (or overwrites) a reverse response mapping for <paramref name="replySubject"/>.
|
||||
/// Records which origin account and original reply subject to route the response back to.
|
||||
/// Go reference: accounts.go addRespMapEntry.
|
||||
/// </summary>
|
||||
public void AddReverseRespMapEntry(string replySubject, string originAccount, string originalReply) =>
|
||||
_reverseResponseMap[replySubject] = new ReverseResponseMapEntry(
|
||||
replySubject, originAccount, originalReply, DateTime.UtcNow);
|
||||
|
||||
/// <summary>
|
||||
/// Looks up the reverse response map entry for <paramref name="replySubject"/>.
|
||||
/// Returns <see langword="null"/> when no mapping exists.
|
||||
/// Go reference: accounts.go checkForReverseEntries.
|
||||
/// </summary>
|
||||
public ReverseResponseMapEntry? CheckForReverseEntries(string replySubject) =>
|
||||
_reverseResponseMap.TryGetValue(replySubject, out var entry) ? entry : null;
|
||||
|
||||
/// <summary>
|
||||
/// Removes the reverse response mapping for <paramref name="replySubject"/>.
|
||||
/// Returns <see langword="true"/> if the entry was found and removed.
|
||||
/// </summary>
|
||||
public bool RemoveReverseRespMapEntry(string replySubject) =>
|
||||
_reverseResponseMap.TryRemove(replySubject, out _);
|
||||
|
||||
/// <summary>The number of active reverse response map entries.</summary>
|
||||
public int ReverseResponseMapCount => _reverseResponseMap.Count;
|
||||
|
||||
/// <summary>Removes all reverse response map entries.</summary>
|
||||
public void ClearReverseResponseMap() => _reverseResponseMap.Clear();
|
||||
|
||||
/// <summary>Returns a snapshot of all reply subjects currently in the reverse response map.</summary>
|
||||
public IReadOnlyList<string> GetReverseResponseMapKeys() => [.. _reverseResponseMap.Keys];
|
||||
|
||||
public void Dispose() => SubList.Dispose();
|
||||
}
|
||||
|
||||
@@ -861,3 +901,19 @@ public sealed record AccountClaimUpdateResult(
|
||||
bool Changed,
|
||||
IReadOnlyList<string> ChangedFields,
|
||||
int UpdateCount);
|
||||
|
||||
/// <summary>
|
||||
/// A single entry in an account's reverse response map.
|
||||
/// Maps a rewritten reply subject back to the original requester's account and subject
|
||||
/// so that service responses can be routed across account boundaries.
|
||||
/// Go reference: server/accounts.go — respMapEntry struct used by addRespMapEntry / checkForReverseEntries.
|
||||
/// </summary>
|
||||
/// <param name="ReplySubject">The rewritten reply subject used by the service provider.</param>
|
||||
/// <param name="OriginAccount">The name of the account that originated the request.</param>
|
||||
/// <param name="OriginalReply">The reply subject the originating client is listening on.</param>
|
||||
/// <param name="CreatedAt">The UTC time at which this mapping was recorded.</param>
|
||||
public sealed record ReverseResponseMapEntry(
|
||||
string ReplySubject,
|
||||
string OriginAccount,
|
||||
string OriginalReply,
|
||||
DateTime CreatedAt);
|
||||
|
||||
Reference in New Issue
Block a user