close inactive sessions after 10 minutes

This commit is contained in:
herby2212 2023-05-01 16:24:15 +02:00
parent af4e111d82
commit 8bb44b85d7
2 changed files with 77 additions and 5 deletions

View File

@ -63,6 +63,9 @@ namespace Emby.Server.Implementations.Session
private readonly ConcurrentDictionary<string, SessionInfo> _activeConnections = new(StringComparer.OrdinalIgnoreCase);
private Timer _idleTimer;
private Timer _inactiveTimer;
private int inactiveMinutesThreshold = 10;
private DtoOptions _itemInfoDtoOptions;
private bool _disposed = false;
@ -171,9 +174,11 @@ namespace Emby.Server.Implementations.Session
if (disposing)
{
_idleTimer?.Dispose();
_inactiveTimer?.Dispose();
}
_idleTimer = null;
_inactiveTimer = null;
_deviceManager.DeviceOptionsUpdated -= OnDeviceManagerDeviceOptionsUpdated;
@ -397,6 +402,15 @@ namespace Emby.Server.Implementations.Session
session.LastPlaybackCheckIn = DateTime.UtcNow;
}
if (info.IsPaused && session.LastPausedDate.HasValue == false)
{
session.LastPausedDate = DateTime.UtcNow;
}
else if (!info.IsPaused)
{
session.LastPausedDate = null;
}
session.PlayState.IsPaused = info.IsPaused;
session.PlayState.PositionTicks = info.PositionTicks;
session.PlayState.MediaSourceId = info.MediaSourceId;
@ -564,9 +578,10 @@ namespace Emby.Server.Implementations.Session
return users;
}
private void StartIdleCheckTimer()
private void StartCheckTimers()
{
_idleTimer ??= new Timer(CheckForIdlePlayback, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
_inactiveTimer ??= new Timer(CheckForInactiveSteams, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
}
private void StopIdleCheckTimer()
@ -578,6 +593,15 @@ namespace Emby.Server.Implementations.Session
}
}
private void StopInactiveCheckTimer()
{
if (_inactiveTimer is not null)
{
_inactiveTimer.Dispose();
_inactiveTimer = null;
}
}
private async void CheckForIdlePlayback(object state)
{
var playingSessions = Sessions.Where(i => i.NowPlayingItem is not null)
@ -613,13 +637,55 @@ namespace Emby.Server.Implementations.Session
playingSessions = Sessions.Where(i => i.NowPlayingItem is not null)
.ToList();
}
if (playingSessions.Count == 0)
else
{
StopIdleCheckTimer();
}
}
private async void CheckForInactiveSteams(object state)
{
var pausedSessions = Sessions.Where(i =>
(i.NowPlayingItem is not null) &&
(i.PlayState.IsPaused == true) &&
(i.LastPausedDate is not null)).ToList();
if (pausedSessions.Count > 0)
{
var inactiveSessions = Sessions.Where(i => (DateTime.UtcNow - i.LastPausedDate).Value.TotalMinutes > inactiveMinutesThreshold).ToList();
foreach (var session in inactiveSessions)
{
_logger.LogDebug("Session {0} has been inactive for {1} minutes. Stopping it.", session.Id, inactiveMinutesThreshold);
try
{
await SendPlaystateCommand(
session.Id,
session.Id,
new PlaystateRequest()
{
Command = PlaystateCommand.Stop,
ControllingUserId = session.UserId.ToString(),
SeekPositionTicks = session.PlayState?.PositionTicks
},
CancellationToken.None).ConfigureAwait(true);
}
catch (Exception ex)
{
_logger.LogDebug(ex, "Error calling SendPlaystateCommand for stopping inactive session {0}.", session.Id);
}
}
}
var playingSessions = Sessions.Where(i => i.NowPlayingItem is not null)
.ToList();
if (playingSessions.Count == 0)
{
StopInactiveCheckTimer();
}
}
private BaseItem GetNowPlayingItem(SessionInfo session, Guid itemId)
{
var item = session.FullNowPlayingItem;
@ -696,7 +762,7 @@ namespace Emby.Server.Implementations.Session
eventArgs,
_logger);
StartIdleCheckTimer();
StartCheckTimers();
}
/// <summary>
@ -790,7 +856,7 @@ namespace Emby.Server.Implementations.Session
session.StartAutomaticProgress(info);
}
StartIdleCheckTimer();
StartCheckTimers();
}
private void OnPlaybackProgress(User user, BaseItem item, PlaybackProgressInfo info)

View File

@ -109,6 +109,12 @@ namespace MediaBrowser.Controller.Session
/// <value>The last playback check in.</value>
public DateTime LastPlaybackCheckIn { get; set; }
/// <summary>
/// Gets or sets the last paused date.
/// </summary>
/// <value>The last paused date.</value>
public DateTime? LastPausedDate { get; set; }
/// <summary>
/// Gets or sets the name of the device.
/// </summary>