tgstation-server 6.12.0
The /tg/station 13 server suite
Loading...
Searching...
No Matches
IdentityCache.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Threading.Tasks;
5
6using Microsoft.Extensions.Logging;
7
11
13{
16 {
21
25 readonly ILogger<IdentityCache> logger;
26
30 readonly Dictionary<long, IdentityCacheObject> cachedIdentities;
31
37 public IdentityCache(IAsyncDelayer asyncDelayer, ILogger<IdentityCache> logger)
38 {
39 this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
40 this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
41
42 cachedIdentities = new Dictionary<long, IdentityCacheObject>();
43 }
44
46 public ValueTask DisposeAsync()
47 {
48 logger.LogTrace("Disposing...");
49 return ValueTaskExtensions.WhenAll(cachedIdentities.Select(x => x.Value.DisposeAsync()));
50 }
51
53 public async ValueTask CacheSystemIdentity(User user, ISystemIdentity systemIdentity, DateTimeOffset expiry)
54 {
55 ArgumentNullException.ThrowIfNull(user);
56 ArgumentNullException.ThrowIfNull(systemIdentity);
57
58 var uid = user.Require(x => x.Id);
59 var sysId = systemIdentity.Uid;
60
61 ValueTask oldIdentityDisposal = ValueTask.CompletedTask;
62 try
63 {
64 lock (cachedIdentities)
65 {
66 logger.LogDebug("Caching system identity {sysId} of user {uid}", sysId, uid);
67
68 if (cachedIdentities.TryGetValue(uid, out var identCache))
69 {
70 logger.LogTrace("Expiring previously cached identity...");
71 oldIdentityDisposal = identCache.DisposeAsync(); // also clears it out
72 }
73
74 identCache = new IdentityCacheObject(
75 systemIdentity.Clone(),
77 () =>
78 {
79 logger.LogDebug("Expiring system identity cache for user {uid}", uid);
80 lock (cachedIdentities)
81 cachedIdentities.Remove(uid);
82 },
83 expiry);
84 cachedIdentities.Add(uid, identCache);
85 }
86 }
87 finally
88 {
89 await oldIdentityDisposal;
90 }
91 }
92
95 {
96 ArgumentNullException.ThrowIfNull(user);
97 var uid = user.Require(x => x.Id);
98 lock (cachedIdentities)
99 if (cachedIdentities.TryGetValue(uid, out var identity))
100 return identity.SystemIdentity.Clone();
101
102 throw new InvalidOperationException("Cached system identity has expired!");
103 }
104 }
105}
Extension methods for the ValueTask and ValueTask<TResult> classes.
static async ValueTask WhenAll(IEnumerable< ValueTask > tasks)
Fully await a given list of tasks .
ISystemIdentity LoadCachedIdentity(User user)
Attempt to load a cached ISystemIdentity.The cached ISystemIdentity.
readonly ILogger< IdentityCache > logger
The ILogger for the IdentityCache.
async ValueTask CacheSystemIdentity(User user, ISystemIdentity systemIdentity, DateTimeOffset expiry)
Keep a user 's systemIdentity alive until an expiry time.A ValueTask representing the running opera...
readonly IAsyncDelayer asyncDelayer
The IAsyncDelayer for the IdentityCache.
IdentityCache(IAsyncDelayer asyncDelayer, ILogger< IdentityCache > logger)
Initializes a new instance of the IdentityCache class.
readonly Dictionary< long, IdentityCacheObject > cachedIdentities
The map of Api.Models.EntityId.Ids to IdentityCacheObjects.
For keeping a specific ISystemIdentity alive for a period of time.
Represents a user on the current global::System.Runtime.InteropServices.OSPlatform.
ISystemIdentity Clone()
Clone the ISystemIdentity creating another copy that must have IDisposable.Dispose called on it.
string Uid
A unique identifier for the user.