Skip to content

Commit 01982eb

Browse files
Fix timestamp frequency mismatch in idle timeout calculation
Convert TimeSpan.Ticks to timestamp ticks using TimeProvider.TimestampFrequency. TimeSpan.Ticks uses 100-nanosecond intervals (10,000,000 per second), but TimeProvider.GetTimestamp() returns ticks based on TimeProvider.TimestampFrequency, which varies by platform (e.g., ~1,000,000,000 on macOS, ~10,000,000 on Windows). This was causing IdleTimeout to be incorrectly calculated, resulting in sessions timing out much faster than configured on platforms with different frequencies. Co-authored-by: eiriktsarpalis <[email protected]>
1 parent ccfeaa4 commit 01982eb

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

src/ModelContextProtocol.AspNetCore/StatefulSessionManager.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,18 @@ internal sealed partial class StatefulSessionManager(
1818

1919
private readonly TimeProvider _timeProvider = httpServerTransportOptions.Value.TimeProvider;
2020
private readonly TimeSpan _idleTimeout = httpServerTransportOptions.Value.IdleTimeout;
21-
private readonly long _idleTimeoutTicks = httpServerTransportOptions.Value.IdleTimeout.Ticks;
21+
private readonly long _idleTimeoutTicks = GetIdleTimeoutInTimestampTicks(httpServerTransportOptions.Value.IdleTimeout, httpServerTransportOptions.Value.TimeProvider);
2222
private readonly int _maxIdleSessionCount = httpServerTransportOptions.Value.MaxIdleSessionCount;
2323

24+
private static long GetIdleTimeoutInTimestampTicks(TimeSpan idleTimeout, TimeProvider timeProvider)
25+
{
26+
// Convert TimeSpan.Ticks (100-nanosecond intervals) to timestamp ticks based on TimeProvider.TimestampFrequency.
27+
// TimeSpan.Ticks uses a fixed frequency of 10,000,000 ticks per second (100ns intervals).
28+
// TimeProvider.GetTimestamp() returns ticks based on TimeProvider.TimestampFrequency, which varies by platform
29+
// (e.g., ~1,000,000,000 on macOS using nanoseconds, ~10,000,000 on Windows using 100ns intervals).
30+
return (long)(idleTimeout.Ticks * timeProvider.TimestampFrequency / (double)TimeSpan.TicksPerSecond);
31+
}
32+
2433
private readonly object _idlePruningLock = new();
2534
private readonly List<long> _idleTimestamps = [];
2635
private readonly List<string> _idleSessionIds = [];

0 commit comments

Comments
 (0)