public async Task SaveSessionInfoAsync(SaveSessionInfoCommand command, CancellationToken cancellationToken = default) { var(sessionInfo, session) = command; if (Computed.IsInvalidating()) { GetSessionInfoAsync(session, default).Ignore(); return; } if (sessionInfo.Id != session.Id) { throw new ArgumentOutOfRangeException(nameof(sessionInfo)); } var now = Clock.Now.ToDateTime(); sessionInfo = sessionInfo with { LastSeenAt = now }; await using var dbContext = await CreateCommandDbContextAsync(cancellationToken).ConfigureAwait(false); var dbSession = await GetOrCreateSessionAsync(dbContext, session, cancellationToken).ConfigureAwait(false); dbSession.LastSeenAt = sessionInfo.LastSeenAt; dbSession.IPAddress = sessionInfo.IPAddress; dbSession.UserAgent = sessionInfo.UserAgent; dbSession.ExtraPropertiesJson = ToJson(sessionInfo.ExtraProperties !.ToDictionary(kv => kv.Key, kv => kv.Value)); await dbContext.SaveChangesAsync(cancellationToken); }
public async Task UpdatePresenceAsync(Session session, CancellationToken cancellationToken = default) { var sessionInfo = await GetSessionInfoAsync(session, cancellationToken).ConfigureAwait(false); var now = Clock.Now.ToDateTime(); var delta = now - sessionInfo.LastSeenAt; if (delta < TimeSpan.FromMinutes(3)) { return; // We don't want to update this too frequently } sessionInfo = sessionInfo with { LastSeenAt = now }; var command = new SaveSessionInfoCommand(sessionInfo, session).MarkServerSide(); await SaveSessionInfoAsync(command, cancellationToken).ConfigureAwait(false); }