浏览代码

Make device/session code async

Patrick Barron 4 年之前
父节点
当前提交
8607b52541

+ 3 - 1
Emby.Dlna/PlayTo/PlayToManager.cs

@@ -171,7 +171,9 @@ namespace Emby.Dlna.PlayTo
                 uuid = uri.ToString().GetMD5().ToString("N", CultureInfo.InvariantCulture);
                 uuid = uri.ToString().GetMD5().ToString("N", CultureInfo.InvariantCulture);
             }
             }
 
 
-            var sessionInfo = _sessionManager.LogSessionActivity("DLNA", _appHost.ApplicationVersionString, uuid, null, uri.OriginalString, null);
+            var sessionInfo = await _sessionManager
+                .LogSessionActivity("DLNA", _appHost.ApplicationVersionString, uuid, null, uri.OriginalString, null)
+                .ConfigureAwait(false);
 
 
             var controller = sessionInfo.SessionControllers.OfType<PlayToController>().FirstOrDefault();
             var controller = sessionInfo.SessionControllers.OfType<PlayToController>().FirstOrDefault();
 
 

+ 6 - 5
Emby.Server.Implementations/HttpServer/Security/SessionContext.cs

@@ -1,6 +1,7 @@
 #pragma warning disable CS1591
 #pragma warning disable CS1591
 
 
 using System;
 using System;
+using System.Threading.Tasks;
 using Jellyfin.Data.Entities;
 using Jellyfin.Data.Entities;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
@@ -23,7 +24,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
             _sessionManager = sessionManager;
             _sessionManager = sessionManager;
         }
         }
 
 
-        public SessionInfo GetSession(HttpContext requestContext)
+        public Task<SessionInfo> GetSession(HttpContext requestContext)
         {
         {
             var authorization = _authContext.GetAuthorizationInfo(requestContext);
             var authorization = _authContext.GetAuthorizationInfo(requestContext);
 
 
@@ -31,19 +32,19 @@ namespace Emby.Server.Implementations.HttpServer.Security
             return _sessionManager.LogSessionActivity(authorization.Client, authorization.Version, authorization.DeviceId, authorization.Device, requestContext.GetNormalizedRemoteIp(), user);
             return _sessionManager.LogSessionActivity(authorization.Client, authorization.Version, authorization.DeviceId, authorization.Device, requestContext.GetNormalizedRemoteIp(), user);
         }
         }
 
 
-        public SessionInfo GetSession(object requestContext)
+        public Task<SessionInfo> GetSession(object requestContext)
         {
         {
             return GetSession((HttpContext)requestContext);
             return GetSession((HttpContext)requestContext);
         }
         }
 
 
-        public User GetUser(HttpContext requestContext)
+        public async Task<User> GetUser(HttpContext requestContext)
         {
         {
-            var session = GetSession(requestContext);
+            var session = await GetSession(requestContext).ConfigureAwait(false);
 
 
             return session == null || session.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(session.UserId);
             return session == null || session.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(session.UserId);
         }
         }
 
 
-        public User GetUser(object requestContext)
+        public Task<User> GetUser(object requestContext)
         {
         {
             return GetUser(((HttpRequest)requestContext).HttpContext);
             return GetUser(((HttpRequest)requestContext).HttpContext);
         }
         }

+ 14 - 12
Emby.Server.Implementations/Session/SessionManager.cs

@@ -254,7 +254,7 @@ namespace Emby.Server.Implementations.Session
         /// <param name="remoteEndPoint">The remote end point.</param>
         /// <param name="remoteEndPoint">The remote end point.</param>
         /// <param name="user">The user.</param>
         /// <param name="user">The user.</param>
         /// <returns>SessionInfo.</returns>
         /// <returns>SessionInfo.</returns>
-        public SessionInfo LogSessionActivity(
+        public async Task<SessionInfo> LogSessionActivity(
             string appName,
             string appName,
             string appVersion,
             string appVersion,
             string deviceId,
             string deviceId,
@@ -280,7 +280,7 @@ namespace Emby.Server.Implementations.Session
             }
             }
 
 
             var activityDate = DateTime.UtcNow;
             var activityDate = DateTime.UtcNow;
-            var session = GetSessionInfo(appName, appVersion, deviceId, deviceName, remoteEndPoint, user);
+            var session = await GetSessionInfo(appName, appVersion, deviceId, deviceName, remoteEndPoint, user).ConfigureAwait(false);
             var lastActivityDate = session.LastActivityDate;
             var lastActivityDate = session.LastActivityDate;
             session.LastActivityDate = activityDate;
             session.LastActivityDate = activityDate;
 
 
@@ -458,7 +458,7 @@ namespace Emby.Server.Implementations.Session
         /// <param name="remoteEndPoint">The remote end point.</param>
         /// <param name="remoteEndPoint">The remote end point.</param>
         /// <param name="user">The user.</param>
         /// <param name="user">The user.</param>
         /// <returns>SessionInfo.</returns>
         /// <returns>SessionInfo.</returns>
-        private SessionInfo GetSessionInfo(
+        private async Task<SessionInfo> GetSessionInfo(
             string appName,
             string appName,
             string appVersion,
             string appVersion,
             string deviceId,
             string deviceId,
@@ -477,9 +477,11 @@ namespace Emby.Server.Implementations.Session
 
 
             CheckDisposed();
             CheckDisposed();
 
 
-            var sessionInfo = _activeConnections.GetOrAdd(
-                key,
-                k => CreateSession(k, appName, appVersion, deviceId, deviceName, remoteEndPoint, user));
+            if (!_activeConnections.TryGetValue(key, out var sessionInfo))
+            {
+                _activeConnections[key] = await CreateSession(key, appName, appVersion, deviceId, deviceName, remoteEndPoint, user).ConfigureAwait(false);
+                sessionInfo = _activeConnections[key];
+            }
 
 
             sessionInfo.UserId = user?.Id ?? Guid.Empty;
             sessionInfo.UserId = user?.Id ?? Guid.Empty;
             sessionInfo.UserName = user?.Username;
             sessionInfo.UserName = user?.Username;
@@ -502,7 +504,7 @@ namespace Emby.Server.Implementations.Session
             return sessionInfo;
             return sessionInfo;
         }
         }
 
 
-        private SessionInfo CreateSession(
+        private async Task<SessionInfo> CreateSession(
             string key,
             string key,
             string appName,
             string appName,
             string appVersion,
             string appVersion,
@@ -532,7 +534,7 @@ namespace Emby.Server.Implementations.Session
                 deviceName = "Network Device";
                 deviceName = "Network Device";
             }
             }
 
 
-            var deviceOptions = _deviceManager.GetDeviceOptions(deviceId);
+            var deviceOptions = await _deviceManager.GetDeviceOptions(deviceId).ConfigureAwait(false);
             if (string.IsNullOrEmpty(deviceOptions.CustomName))
             if (string.IsNullOrEmpty(deviceOptions.CustomName))
             {
             {
                 sessionInfo.DeviceName = deviceName;
                 sessionInfo.DeviceName = deviceName;
@@ -1507,13 +1509,13 @@ namespace Emby.Server.Implementations.Session
 
 
             var token = GetAuthorizationToken(user, request.DeviceId, request.App, request.AppVersion, request.DeviceName);
             var token = GetAuthorizationToken(user, request.DeviceId, request.App, request.AppVersion, request.DeviceName);
 
 
-            var session = LogSessionActivity(
+            var session = await LogSessionActivity(
                 request.App,
                 request.App,
                 request.AppVersion,
                 request.AppVersion,
                 request.DeviceId,
                 request.DeviceId,
                 request.DeviceName,
                 request.DeviceName,
                 request.RemoteEndPoint,
                 request.RemoteEndPoint,
-                user);
+                user).ConfigureAwait(false);
 
 
             var returnResult = new AuthenticationResult
             var returnResult = new AuthenticationResult
             {
             {
@@ -1811,7 +1813,7 @@ namespace Emby.Server.Implementations.Session
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public SessionInfo GetSessionByAuthenticationToken(AuthenticationInfo info, string deviceId, string remoteEndpoint, string appVersion)
+        public Task<SessionInfo> GetSessionByAuthenticationToken(AuthenticationInfo info, string deviceId, string remoteEndpoint, string appVersion)
         {
         {
             if (info == null)
             if (info == null)
             {
             {
@@ -1844,7 +1846,7 @@ namespace Emby.Server.Implementations.Session
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public SessionInfo GetSessionByAuthenticationToken(string token, string deviceId, string remoteEndpoint)
+        public Task<SessionInfo> GetSessionByAuthenticationToken(string token, string deviceId, string remoteEndpoint)
         {
         {
             var items = _authRepo.Get(new AuthenticationInfoQuery
             var items = _authRepo.Get(new AuthenticationInfoQuery
             {
             {

+ 2 - 2
Emby.Server.Implementations/Session/SessionWebSocketListener.cs

@@ -97,7 +97,7 @@ namespace Emby.Server.Implementations.Session
         /// <inheritdoc />
         /// <inheritdoc />
         public async Task ProcessWebSocketConnectedAsync(IWebSocketConnection connection)
         public async Task ProcessWebSocketConnectedAsync(IWebSocketConnection connection)
         {
         {
-            var session = GetSession(connection.QueryString, connection.RemoteEndPoint.ToString());
+            var session = await GetSession(connection.QueryString, connection.RemoteEndPoint.ToString()).ConfigureAwait(false);
             if (session != null)
             if (session != null)
             {
             {
                 EnsureController(session, connection);
                 EnsureController(session, connection);
@@ -109,7 +109,7 @@ namespace Emby.Server.Implementations.Session
             }
             }
         }
         }
 
 
-        private SessionInfo GetSession(IQueryCollection queryString, string remoteEndpoint)
+        private Task<SessionInfo> GetSession(IQueryCollection queryString, string remoteEndpoint)
         {
         {
             if (queryString == null)
             if (queryString == null)
             {
             {

+ 2 - 2
Jellyfin.Api/Controllers/DevicesController.cs

@@ -86,9 +86,9 @@ namespace Jellyfin.Api.Controllers
         [HttpGet("Options")]
         [HttpGet("Options")]
         [ProducesResponseType(StatusCodes.Status200OK)]
         [ProducesResponseType(StatusCodes.Status200OK)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
-        public ActionResult<DeviceOptions> GetDeviceOptions([FromQuery, Required] string id)
+        public async Task<ActionResult<DeviceOptions>> GetDeviceOptions([FromQuery, Required] string id)
         {
         {
-            var deviceInfo = _deviceManager.GetDeviceOptions(id);
+            var deviceInfo = await _deviceManager.GetDeviceOptions(id).ConfigureAwait(false);
             if (deviceInfo == null)
             if (deviceInfo == null)
             {
             {
                 return NotFound();
                 return NotFound();

+ 13 - 13
Jellyfin.Api/Controllers/LiveTvController.cs

@@ -429,10 +429,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Tuners/{tunerId}/Reset")]
         [HttpPost("Tuners/{tunerId}/Reset")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [Authorize(Policy = Policies.DefaultAuthorization)]
-        public ActionResult ResetTuner([FromRoute, Required] string tunerId)
+        public async Task<ActionResult> ResetTuner([FromRoute, Required] string tunerId)
         {
         {
-            AssertUserCanManageLiveTv();
-            _liveTvManager.ResetTuner(tunerId, CancellationToken.None);
+            await AssertUserCanManageLiveTv().ConfigureAwait(false);
+            await _liveTvManager.ResetTuner(tunerId, CancellationToken.None).ConfigureAwait(false);
             return NoContent();
             return NoContent();
         }
         }
 
 
@@ -761,9 +761,9 @@ namespace Jellyfin.Api.Controllers
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
-        public ActionResult DeleteRecording([FromRoute, Required] Guid recordingId)
+        public async Task<ActionResult> DeleteRecording([FromRoute, Required] Guid recordingId)
         {
         {
-            AssertUserCanManageLiveTv();
+            await AssertUserCanManageLiveTv().ConfigureAwait(false);
 
 
             var item = _libraryManager.GetItemById(recordingId);
             var item = _libraryManager.GetItemById(recordingId);
             if (item == null)
             if (item == null)
@@ -790,7 +790,7 @@ namespace Jellyfin.Api.Controllers
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         public async Task<ActionResult> CancelTimer([FromRoute, Required] string timerId)
         public async Task<ActionResult> CancelTimer([FromRoute, Required] string timerId)
         {
         {
-            AssertUserCanManageLiveTv();
+            await AssertUserCanManageLiveTv().ConfigureAwait(false);
             await _liveTvManager.CancelTimer(timerId).ConfigureAwait(false);
             await _liveTvManager.CancelTimer(timerId).ConfigureAwait(false);
             return NoContent();
             return NoContent();
         }
         }
@@ -808,7 +808,7 @@ namespace Jellyfin.Api.Controllers
         [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "timerId", Justification = "Imported from ServiceStack")]
         [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "timerId", Justification = "Imported from ServiceStack")]
         public async Task<ActionResult> UpdateTimer([FromRoute, Required] string timerId, [FromBody] TimerInfoDto timerInfo)
         public async Task<ActionResult> UpdateTimer([FromRoute, Required] string timerId, [FromBody] TimerInfoDto timerInfo)
         {
         {
-            AssertUserCanManageLiveTv();
+            await AssertUserCanManageLiveTv().ConfigureAwait(false);
             await _liveTvManager.UpdateTimer(timerInfo, CancellationToken.None).ConfigureAwait(false);
             await _liveTvManager.UpdateTimer(timerInfo, CancellationToken.None).ConfigureAwait(false);
             return NoContent();
             return NoContent();
         }
         }
@@ -824,7 +824,7 @@ namespace Jellyfin.Api.Controllers
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         public async Task<ActionResult> CreateTimer([FromBody] TimerInfoDto timerInfo)
         public async Task<ActionResult> CreateTimer([FromBody] TimerInfoDto timerInfo)
         {
         {
-            AssertUserCanManageLiveTv();
+            await AssertUserCanManageLiveTv().ConfigureAwait(false);
             await _liveTvManager.CreateTimer(timerInfo, CancellationToken.None).ConfigureAwait(false);
             await _liveTvManager.CreateTimer(timerInfo, CancellationToken.None).ConfigureAwait(false);
             return NoContent();
             return NoContent();
         }
         }
@@ -882,7 +882,7 @@ namespace Jellyfin.Api.Controllers
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         public async Task<ActionResult> CancelSeriesTimer([FromRoute, Required] string timerId)
         public async Task<ActionResult> CancelSeriesTimer([FromRoute, Required] string timerId)
         {
         {
-            AssertUserCanManageLiveTv();
+            await AssertUserCanManageLiveTv().ConfigureAwait(false);
             await _liveTvManager.CancelSeriesTimer(timerId).ConfigureAwait(false);
             await _liveTvManager.CancelSeriesTimer(timerId).ConfigureAwait(false);
             return NoContent();
             return NoContent();
         }
         }
@@ -900,7 +900,7 @@ namespace Jellyfin.Api.Controllers
         [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "timerId", Justification = "Imported from ServiceStack")]
         [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "timerId", Justification = "Imported from ServiceStack")]
         public async Task<ActionResult> UpdateSeriesTimer([FromRoute, Required] string timerId, [FromBody] SeriesTimerInfoDto seriesTimerInfo)
         public async Task<ActionResult> UpdateSeriesTimer([FromRoute, Required] string timerId, [FromBody] SeriesTimerInfoDto seriesTimerInfo)
         {
         {
-            AssertUserCanManageLiveTv();
+            await AssertUserCanManageLiveTv().ConfigureAwait(false);
             await _liveTvManager.UpdateSeriesTimer(seriesTimerInfo, CancellationToken.None).ConfigureAwait(false);
             await _liveTvManager.UpdateSeriesTimer(seriesTimerInfo, CancellationToken.None).ConfigureAwait(false);
             return NoContent();
             return NoContent();
         }
         }
@@ -916,7 +916,7 @@ namespace Jellyfin.Api.Controllers
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         public async Task<ActionResult> CreateSeriesTimer([FromBody] SeriesTimerInfoDto seriesTimerInfo)
         public async Task<ActionResult> CreateSeriesTimer([FromBody] SeriesTimerInfoDto seriesTimerInfo)
         {
         {
-            AssertUserCanManageLiveTv();
+            await AssertUserCanManageLiveTv().ConfigureAwait(false);
             await _liveTvManager.CreateSeriesTimer(seriesTimerInfo, CancellationToken.None).ConfigureAwait(false);
             await _liveTvManager.CreateSeriesTimer(seriesTimerInfo, CancellationToken.None).ConfigureAwait(false);
             return NoContent();
             return NoContent();
         }
         }
@@ -1215,9 +1215,9 @@ namespace Jellyfin.Api.Controllers
             return new FileStreamResult(liveStream, MimeTypes.GetMimeType("file." + container));
             return new FileStreamResult(liveStream, MimeTypes.GetMimeType("file." + container));
         }
         }
 
 
-        private void AssertUserCanManageLiveTv()
+        private async Task AssertUserCanManageLiveTv()
         {
         {
-            var user = _sessionContext.GetUser(Request);
+            var user = await _sessionContext.GetUser(Request).ConfigureAwait(false);
 
 
             if (user == null)
             if (user == null)
             {
             {

+ 10 - 10
Jellyfin.Api/Controllers/PlaystateController.cs

@@ -72,13 +72,13 @@ namespace Jellyfin.Api.Controllers
         /// <returns>An <see cref="OkResult"/> containing the <see cref="UserItemDataDto"/>.</returns>
         /// <returns>An <see cref="OkResult"/> containing the <see cref="UserItemDataDto"/>.</returns>
         [HttpPost("Users/{userId}/PlayedItems/{itemId}")]
         [HttpPost("Users/{userId}/PlayedItems/{itemId}")]
         [ProducesResponseType(StatusCodes.Status200OK)]
         [ProducesResponseType(StatusCodes.Status200OK)]
-        public ActionResult<UserItemDataDto> MarkPlayedItem(
+        public async Task<ActionResult<UserItemDataDto>> MarkPlayedItem(
             [FromRoute, Required] Guid userId,
             [FromRoute, Required] Guid userId,
             [FromRoute, Required] Guid itemId,
             [FromRoute, Required] Guid itemId,
             [FromQuery, ModelBinder(typeof(LegacyDateTimeModelBinder))] DateTime? datePlayed)
             [FromQuery, ModelBinder(typeof(LegacyDateTimeModelBinder))] DateTime? datePlayed)
         {
         {
             var user = _userManager.GetUserById(userId);
             var user = _userManager.GetUserById(userId);
-            var session = RequestHelpers.GetSession(_sessionManager, _authContext, Request);
+            var session = await RequestHelpers.GetSession(_sessionManager, _authContext, Request).ConfigureAwait(false);
             var dto = UpdatePlayedStatus(user, itemId, true, datePlayed);
             var dto = UpdatePlayedStatus(user, itemId, true, datePlayed);
             foreach (var additionalUserInfo in session.AdditionalUsers)
             foreach (var additionalUserInfo in session.AdditionalUsers)
             {
             {
@@ -98,10 +98,10 @@ namespace Jellyfin.Api.Controllers
         /// <returns>A <see cref="OkResult"/> containing the <see cref="UserItemDataDto"/>.</returns>
         /// <returns>A <see cref="OkResult"/> containing the <see cref="UserItemDataDto"/>.</returns>
         [HttpDelete("Users/{userId}/PlayedItems/{itemId}")]
         [HttpDelete("Users/{userId}/PlayedItems/{itemId}")]
         [ProducesResponseType(StatusCodes.Status200OK)]
         [ProducesResponseType(StatusCodes.Status200OK)]
-        public ActionResult<UserItemDataDto> MarkUnplayedItem([FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId)
+        public async Task<ActionResult<UserItemDataDto>> MarkUnplayedItem([FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId)
         {
         {
             var user = _userManager.GetUserById(userId);
             var user = _userManager.GetUserById(userId);
-            var session = RequestHelpers.GetSession(_sessionManager, _authContext, Request);
+            var session = await RequestHelpers.GetSession(_sessionManager, _authContext, Request).ConfigureAwait(false);
             var dto = UpdatePlayedStatus(user, itemId, false, null);
             var dto = UpdatePlayedStatus(user, itemId, false, null);
             foreach (var additionalUserInfo in session.AdditionalUsers)
             foreach (var additionalUserInfo in session.AdditionalUsers)
             {
             {
@@ -123,7 +123,7 @@ namespace Jellyfin.Api.Controllers
         public async Task<ActionResult> ReportPlaybackStart([FromBody] PlaybackStartInfo playbackStartInfo)
         public async Task<ActionResult> ReportPlaybackStart([FromBody] PlaybackStartInfo playbackStartInfo)
         {
         {
             playbackStartInfo.PlayMethod = ValidatePlayMethod(playbackStartInfo.PlayMethod, playbackStartInfo.PlaySessionId);
             playbackStartInfo.PlayMethod = ValidatePlayMethod(playbackStartInfo.PlayMethod, playbackStartInfo.PlaySessionId);
-            playbackStartInfo.SessionId = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
+            playbackStartInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
             await _sessionManager.OnPlaybackStart(playbackStartInfo).ConfigureAwait(false);
             await _sessionManager.OnPlaybackStart(playbackStartInfo).ConfigureAwait(false);
             return NoContent();
             return NoContent();
         }
         }
@@ -139,7 +139,7 @@ namespace Jellyfin.Api.Controllers
         public async Task<ActionResult> ReportPlaybackProgress([FromBody] PlaybackProgressInfo playbackProgressInfo)
         public async Task<ActionResult> ReportPlaybackProgress([FromBody] PlaybackProgressInfo playbackProgressInfo)
         {
         {
             playbackProgressInfo.PlayMethod = ValidatePlayMethod(playbackProgressInfo.PlayMethod, playbackProgressInfo.PlaySessionId);
             playbackProgressInfo.PlayMethod = ValidatePlayMethod(playbackProgressInfo.PlayMethod, playbackProgressInfo.PlaySessionId);
-            playbackProgressInfo.SessionId = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
+            playbackProgressInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
             await _sessionManager.OnPlaybackProgress(playbackProgressInfo).ConfigureAwait(false);
             await _sessionManager.OnPlaybackProgress(playbackProgressInfo).ConfigureAwait(false);
             return NoContent();
             return NoContent();
         }
         }
@@ -174,7 +174,7 @@ namespace Jellyfin.Api.Controllers
                 await _transcodingJobHelper.KillTranscodingJobs(_authContext.GetAuthorizationInfo(Request).DeviceId, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
                 await _transcodingJobHelper.KillTranscodingJobs(_authContext.GetAuthorizationInfo(Request).DeviceId, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
             }
             }
 
 
-            playbackStopInfo.SessionId = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
+            playbackStopInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
             await _sessionManager.OnPlaybackStopped(playbackStopInfo).ConfigureAwait(false);
             await _sessionManager.OnPlaybackStopped(playbackStopInfo).ConfigureAwait(false);
             return NoContent();
             return NoContent();
         }
         }
@@ -220,7 +220,7 @@ namespace Jellyfin.Api.Controllers
             };
             };
 
 
             playbackStartInfo.PlayMethod = ValidatePlayMethod(playbackStartInfo.PlayMethod, playbackStartInfo.PlaySessionId);
             playbackStartInfo.PlayMethod = ValidatePlayMethod(playbackStartInfo.PlayMethod, playbackStartInfo.PlaySessionId);
-            playbackStartInfo.SessionId = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
+            playbackStartInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
             await _sessionManager.OnPlaybackStart(playbackStartInfo).ConfigureAwait(false);
             await _sessionManager.OnPlaybackStart(playbackStartInfo).ConfigureAwait(false);
             return NoContent();
             return NoContent();
         }
         }
@@ -278,7 +278,7 @@ namespace Jellyfin.Api.Controllers
             };
             };
 
 
             playbackProgressInfo.PlayMethod = ValidatePlayMethod(playbackProgressInfo.PlayMethod, playbackProgressInfo.PlaySessionId);
             playbackProgressInfo.PlayMethod = ValidatePlayMethod(playbackProgressInfo.PlayMethod, playbackProgressInfo.PlaySessionId);
-            playbackProgressInfo.SessionId = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
+            playbackProgressInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
             await _sessionManager.OnPlaybackProgress(playbackProgressInfo).ConfigureAwait(false);
             await _sessionManager.OnPlaybackProgress(playbackProgressInfo).ConfigureAwait(false);
             return NoContent();
             return NoContent();
         }
         }
@@ -323,7 +323,7 @@ namespace Jellyfin.Api.Controllers
                 await _transcodingJobHelper.KillTranscodingJobs(_authContext.GetAuthorizationInfo(Request).DeviceId, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
                 await _transcodingJobHelper.KillTranscodingJobs(_authContext.GetAuthorizationInfo(Request).DeviceId, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
             }
             }
 
 
-            playbackStopInfo.SessionId = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
+            playbackStopInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
             await _sessionManager.OnPlaybackStopped(playbackStopInfo).ConfigureAwait(false);
             await _sessionManager.OnPlaybackStopped(playbackStopInfo).ConfigureAwait(false);
             return NoContent();
             return NoContent();
         }
         }

+ 42 - 30
Jellyfin.Api/Controllers/SessionController.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations;
 using System.Linq;
 using System.Linq;
 using System.Threading;
 using System.Threading;
+using System.Threading.Tasks;
 using Jellyfin.Api.Constants;
 using Jellyfin.Api.Constants;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.ModelBinders;
 using Jellyfin.Api.ModelBinders;
@@ -124,7 +125,7 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Sessions/{sessionId}/Viewing")]
         [HttpPost("Sessions/{sessionId}/Viewing")]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
-        public ActionResult DisplayContent(
+        public async Task<ActionResult> DisplayContent(
             [FromRoute, Required] string sessionId,
             [FromRoute, Required] string sessionId,
             [FromQuery, Required] string itemType,
             [FromQuery, Required] string itemType,
             [FromQuery, Required] string itemId,
             [FromQuery, Required] string itemId,
@@ -137,11 +138,12 @@ namespace Jellyfin.Api.Controllers
                 ItemType = itemType
                 ItemType = itemType
             };
             };
 
 
-            _sessionManager.SendBrowseCommand(
-                RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id,
+            await _sessionManager.SendBrowseCommand(
+                await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false),
                 sessionId,
                 sessionId,
                 command,
                 command,
-                CancellationToken.None);
+                CancellationToken.None)
+                .ConfigureAwait(false);
 
 
             return NoContent();
             return NoContent();
         }
         }
@@ -158,7 +160,7 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Sessions/{sessionId}/Playing")]
         [HttpPost("Sessions/{sessionId}/Playing")]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
-        public ActionResult Play(
+        public async Task<ActionResult> Play(
             [FromRoute, Required] string sessionId,
             [FromRoute, Required] string sessionId,
             [FromQuery, Required] PlayCommand playCommand,
             [FromQuery, Required] PlayCommand playCommand,
             [FromQuery, Required, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] itemIds,
             [FromQuery, Required, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] itemIds,
@@ -171,11 +173,12 @@ namespace Jellyfin.Api.Controllers
                 PlayCommand = playCommand
                 PlayCommand = playCommand
             };
             };
 
 
-            _sessionManager.SendPlayCommand(
-                RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id,
+            await _sessionManager.SendPlayCommand(
+                await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false),
                 sessionId,
                 sessionId,
                 playRequest,
                 playRequest,
-                CancellationToken.None);
+                CancellationToken.None)
+                .ConfigureAwait(false);
 
 
             return NoContent();
             return NoContent();
         }
         }
@@ -192,14 +195,14 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Sessions/{sessionId}/Playing/{command}")]
         [HttpPost("Sessions/{sessionId}/Playing/{command}")]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
-        public ActionResult SendPlaystateCommand(
+        public async Task<ActionResult> SendPlaystateCommand(
             [FromRoute, Required] string sessionId,
             [FromRoute, Required] string sessionId,
             [FromRoute, Required] PlaystateCommand command,
             [FromRoute, Required] PlaystateCommand command,
             [FromQuery] long? seekPositionTicks,
             [FromQuery] long? seekPositionTicks,
             [FromQuery] string? controllingUserId)
             [FromQuery] string? controllingUserId)
         {
         {
-            _sessionManager.SendPlaystateCommand(
-                RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id,
+            await _sessionManager.SendPlaystateCommand(
+                await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false),
                 sessionId,
                 sessionId,
                 new PlaystateRequest()
                 new PlaystateRequest()
                 {
                 {
@@ -207,7 +210,8 @@ namespace Jellyfin.Api.Controllers
                     ControllingUserId = controllingUserId,
                     ControllingUserId = controllingUserId,
                     SeekPositionTicks = seekPositionTicks,
                     SeekPositionTicks = seekPositionTicks,
                 },
                 },
-                CancellationToken.None);
+                CancellationToken.None)
+                .ConfigureAwait(false);
 
 
             return NoContent();
             return NoContent();
         }
         }
@@ -222,18 +226,18 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Sessions/{sessionId}/System/{command}")]
         [HttpPost("Sessions/{sessionId}/System/{command}")]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
-        public ActionResult SendSystemCommand(
+        public async Task<ActionResult> SendSystemCommand(
             [FromRoute, Required] string sessionId,
             [FromRoute, Required] string sessionId,
             [FromRoute, Required] GeneralCommandType command)
             [FromRoute, Required] GeneralCommandType command)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authContext, Request).ConfigureAwait(false);
             var generalCommand = new GeneralCommand
             var generalCommand = new GeneralCommand
             {
             {
                 Name = command,
                 Name = command,
                 ControllingUserId = currentSession.UserId
                 ControllingUserId = currentSession.UserId
             };
             };
 
 
-            _sessionManager.SendGeneralCommand(currentSession.Id, sessionId, generalCommand, CancellationToken.None);
+            await _sessionManager.SendGeneralCommand(currentSession.Id, sessionId, generalCommand, CancellationToken.None);
 
 
             return NoContent();
             return NoContent();
         }
         }
@@ -248,11 +252,11 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Sessions/{sessionId}/Command/{command}")]
         [HttpPost("Sessions/{sessionId}/Command/{command}")]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
-        public ActionResult SendGeneralCommand(
+        public async Task<ActionResult> SendGeneralCommand(
             [FromRoute, Required] string sessionId,
             [FromRoute, Required] string sessionId,
             [FromRoute, Required] GeneralCommandType command)
             [FromRoute, Required] GeneralCommandType command)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authContext, Request).ConfigureAwait(false);
 
 
             var generalCommand = new GeneralCommand
             var generalCommand = new GeneralCommand
             {
             {
@@ -260,7 +264,8 @@ namespace Jellyfin.Api.Controllers
                 ControllingUserId = currentSession.UserId
                 ControllingUserId = currentSession.UserId
             };
             };
 
 
-            _sessionManager.SendGeneralCommand(currentSession.Id, sessionId, generalCommand, CancellationToken.None);
+            await _sessionManager.SendGeneralCommand(currentSession.Id, sessionId, generalCommand, CancellationToken.None)
+                .ConfigureAwait(false);
 
 
             return NoContent();
             return NoContent();
         }
         }
@@ -275,11 +280,12 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Sessions/{sessionId}/Command")]
         [HttpPost("Sessions/{sessionId}/Command")]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
-        public ActionResult SendFullGeneralCommand(
+        public async Task<ActionResult> SendFullGeneralCommand(
             [FromRoute, Required] string sessionId,
             [FromRoute, Required] string sessionId,
             [FromBody, Required] GeneralCommand command)
             [FromBody, Required] GeneralCommand command)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authContext, Request)
+                .ConfigureAwait(false);
 
 
             if (command == null)
             if (command == null)
             {
             {
@@ -288,11 +294,12 @@ namespace Jellyfin.Api.Controllers
 
 
             command.ControllingUserId = currentSession.UserId;
             command.ControllingUserId = currentSession.UserId;
 
 
-            _sessionManager.SendGeneralCommand(
+            await _sessionManager.SendGeneralCommand(
                 currentSession.Id,
                 currentSession.Id,
                 sessionId,
                 sessionId,
                 command,
                 command,
-                CancellationToken.None);
+                CancellationToken.None)
+                .ConfigureAwait(false);
 
 
             return NoContent();
             return NoContent();
         }
         }
@@ -309,7 +316,7 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Sessions/{sessionId}/Message")]
         [HttpPost("Sessions/{sessionId}/Message")]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
-        public ActionResult SendMessageCommand(
+        public async Task<ActionResult> SendMessageCommand(
             [FromRoute, Required] string sessionId,
             [FromRoute, Required] string sessionId,
             [FromQuery, Required] string text,
             [FromQuery, Required] string text,
             [FromQuery] string? header,
             [FromQuery] string? header,
@@ -322,7 +329,12 @@ namespace Jellyfin.Api.Controllers
                 Text = text
                 Text = text
             };
             };
 
 
-            _sessionManager.SendMessageCommand(RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id, sessionId, command, CancellationToken.None);
+            await _sessionManager.SendMessageCommand(
+                await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false),
+                sessionId,
+                command,
+                CancellationToken.None)
+                .ConfigureAwait(false);
 
 
             return NoContent();
             return NoContent();
         }
         }
@@ -377,7 +389,7 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Sessions/Capabilities")]
         [HttpPost("Sessions/Capabilities")]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
-        public ActionResult PostCapabilities(
+        public async Task<ActionResult> PostCapabilities(
             [FromQuery] string? id,
             [FromQuery] string? id,
             [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] playableMediaTypes,
             [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] playableMediaTypes,
             [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] GeneralCommandType[] supportedCommands,
             [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] GeneralCommandType[] supportedCommands,
@@ -387,7 +399,7 @@ namespace Jellyfin.Api.Controllers
         {
         {
             if (string.IsNullOrWhiteSpace(id))
             if (string.IsNullOrWhiteSpace(id))
             {
             {
-                id = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
+                id = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
             }
             }
 
 
             _sessionManager.ReportCapabilities(id, new ClientCapabilities
             _sessionManager.ReportCapabilities(id, new ClientCapabilities
@@ -411,13 +423,13 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Sessions/Capabilities/Full")]
         [HttpPost("Sessions/Capabilities/Full")]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
-        public ActionResult PostFullCapabilities(
+        public async Task<ActionResult> PostFullCapabilities(
             [FromQuery] string? id,
             [FromQuery] string? id,
             [FromBody, Required] ClientCapabilitiesDto capabilities)
             [FromBody, Required] ClientCapabilitiesDto capabilities)
         {
         {
             if (string.IsNullOrWhiteSpace(id))
             if (string.IsNullOrWhiteSpace(id))
             {
             {
-                id = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
+                id = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
             }
             }
 
 
             _sessionManager.ReportCapabilities(id, capabilities.ToClientCapabilities());
             _sessionManager.ReportCapabilities(id, capabilities.ToClientCapabilities());
@@ -435,11 +447,11 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Sessions/Viewing")]
         [HttpPost("Sessions/Viewing")]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [Authorize(Policy = Policies.DefaultAuthorization)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
-        public ActionResult ReportViewing(
+        public async Task<ActionResult> ReportViewing(
             [FromQuery] string? sessionId,
             [FromQuery] string? sessionId,
             [FromQuery, Required] string? itemId)
             [FromQuery, Required] string? itemId)
         {
         {
-            string session = sessionId ?? RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
+            string session = sessionId ?? await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
 
 
             _sessionManager.ReportNowViewingItem(session, itemId);
             _sessionManager.ReportNowViewingItem(session, itemId);
             return NoContent();
             return NoContent();

+ 43 - 42
Jellyfin.Api/Controllers/SyncPlayController.cs

@@ -1,6 +1,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations;
 using System.Threading;
 using System.Threading;
+using System.Threading.Tasks;
 using Jellyfin.Api.Constants;
 using Jellyfin.Api.Constants;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.Models.SyncPlayDtos;
 using Jellyfin.Api.Models.SyncPlayDtos;
@@ -51,10 +52,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("New")]
         [HttpPost("New")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayCreateGroup)]
         [Authorize(Policy = Policies.SyncPlayCreateGroup)]
-        public ActionResult SyncPlayCreateGroup(
+        public async Task<ActionResult> SyncPlayCreateGroup(
             [FromBody, Required] NewGroupRequestDto requestData)
             [FromBody, Required] NewGroupRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new NewGroupRequest(requestData.GroupName);
             var syncPlayRequest = new NewGroupRequest(requestData.GroupName);
             _syncPlayManager.NewGroup(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.NewGroup(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -69,10 +70,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Join")]
         [HttpPost("Join")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayJoinGroup)]
         [Authorize(Policy = Policies.SyncPlayJoinGroup)]
-        public ActionResult SyncPlayJoinGroup(
+        public async Task<ActionResult> SyncPlayJoinGroup(
             [FromBody, Required] JoinGroupRequestDto requestData)
             [FromBody, Required] JoinGroupRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new JoinGroupRequest(requestData.GroupId);
             var syncPlayRequest = new JoinGroupRequest(requestData.GroupId);
             _syncPlayManager.JoinGroup(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.JoinGroup(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -86,9 +87,9 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Leave")]
         [HttpPost("Leave")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlayLeaveGroup()
+        public async Task<ActionResult> SyncPlayLeaveGroup()
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new LeaveGroupRequest();
             var syncPlayRequest = new LeaveGroupRequest();
             _syncPlayManager.LeaveGroup(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.LeaveGroup(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -102,9 +103,9 @@ namespace Jellyfin.Api.Controllers
         [HttpGet("List")]
         [HttpGet("List")]
         [ProducesResponseType(StatusCodes.Status200OK)]
         [ProducesResponseType(StatusCodes.Status200OK)]
         [Authorize(Policy = Policies.SyncPlayJoinGroup)]
         [Authorize(Policy = Policies.SyncPlayJoinGroup)]
-        public ActionResult<IEnumerable<GroupInfoDto>> SyncPlayGetGroups()
+        public async Task<ActionResult<IEnumerable<GroupInfoDto>>> SyncPlayGetGroups()
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new ListGroupsRequest();
             var syncPlayRequest = new ListGroupsRequest();
             return Ok(_syncPlayManager.ListGroups(currentSession, syncPlayRequest));
             return Ok(_syncPlayManager.ListGroups(currentSession, syncPlayRequest));
         }
         }
@@ -118,10 +119,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("SetNewQueue")]
         [HttpPost("SetNewQueue")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlaySetNewQueue(
+        public async Task<ActionResult> SyncPlaySetNewQueue(
             [FromBody, Required] PlayRequestDto requestData)
             [FromBody, Required] PlayRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new PlayGroupRequest(
             var syncPlayRequest = new PlayGroupRequest(
                 requestData.PlayingQueue,
                 requestData.PlayingQueue,
                 requestData.PlayingItemPosition,
                 requestData.PlayingItemPosition,
@@ -139,10 +140,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("SetPlaylistItem")]
         [HttpPost("SetPlaylistItem")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlaySetPlaylistItem(
+        public async Task<ActionResult> SyncPlaySetPlaylistItem(
             [FromBody, Required] SetPlaylistItemRequestDto requestData)
             [FromBody, Required] SetPlaylistItemRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new SetPlaylistItemGroupRequest(requestData.PlaylistItemId);
             var syncPlayRequest = new SetPlaylistItemGroupRequest(requestData.PlaylistItemId);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -157,10 +158,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("RemoveFromPlaylist")]
         [HttpPost("RemoveFromPlaylist")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlayRemoveFromPlaylist(
+        public async Task<ActionResult> SyncPlayRemoveFromPlaylist(
             [FromBody, Required] RemoveFromPlaylistRequestDto requestData)
             [FromBody, Required] RemoveFromPlaylistRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new RemoveFromPlaylistGroupRequest(requestData.PlaylistItemIds);
             var syncPlayRequest = new RemoveFromPlaylistGroupRequest(requestData.PlaylistItemIds);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -175,10 +176,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("MovePlaylistItem")]
         [HttpPost("MovePlaylistItem")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlayMovePlaylistItem(
+        public async Task<ActionResult> SyncPlayMovePlaylistItem(
             [FromBody, Required] MovePlaylistItemRequestDto requestData)
             [FromBody, Required] MovePlaylistItemRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new MovePlaylistItemGroupRequest(requestData.PlaylistItemId, requestData.NewIndex);
             var syncPlayRequest = new MovePlaylistItemGroupRequest(requestData.PlaylistItemId, requestData.NewIndex);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -193,10 +194,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Queue")]
         [HttpPost("Queue")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlayQueue(
+        public async Task<ActionResult> SyncPlayQueue(
             [FromBody, Required] QueueRequestDto requestData)
             [FromBody, Required] QueueRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new QueueGroupRequest(requestData.ItemIds, requestData.Mode);
             var syncPlayRequest = new QueueGroupRequest(requestData.ItemIds, requestData.Mode);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -210,9 +211,9 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Unpause")]
         [HttpPost("Unpause")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlayUnpause()
+        public async Task<ActionResult> SyncPlayUnpause()
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new UnpauseGroupRequest();
             var syncPlayRequest = new UnpauseGroupRequest();
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -226,9 +227,9 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Pause")]
         [HttpPost("Pause")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlayPause()
+        public async Task<ActionResult> SyncPlayPause()
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new PauseGroupRequest();
             var syncPlayRequest = new PauseGroupRequest();
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -242,9 +243,9 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Stop")]
         [HttpPost("Stop")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlayStop()
+        public async Task<ActionResult> SyncPlayStop()
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new StopGroupRequest();
             var syncPlayRequest = new StopGroupRequest();
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -259,10 +260,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Seek")]
         [HttpPost("Seek")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlaySeek(
+        public async Task<ActionResult> SyncPlaySeek(
             [FromBody, Required] SeekRequestDto requestData)
             [FromBody, Required] SeekRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new SeekGroupRequest(requestData.PositionTicks);
             var syncPlayRequest = new SeekGroupRequest(requestData.PositionTicks);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -277,10 +278,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Buffering")]
         [HttpPost("Buffering")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlayBuffering(
+        public async Task<ActionResult> SyncPlayBuffering(
             [FromBody, Required] BufferRequestDto requestData)
             [FromBody, Required] BufferRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new BufferGroupRequest(
             var syncPlayRequest = new BufferGroupRequest(
                 requestData.When,
                 requestData.When,
                 requestData.PositionTicks,
                 requestData.PositionTicks,
@@ -299,10 +300,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("Ready")]
         [HttpPost("Ready")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlayReady(
+        public async Task<ActionResult> SyncPlayReady(
             [FromBody, Required] ReadyRequestDto requestData)
             [FromBody, Required] ReadyRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new ReadyGroupRequest(
             var syncPlayRequest = new ReadyGroupRequest(
                 requestData.When,
                 requestData.When,
                 requestData.PositionTicks,
                 requestData.PositionTicks,
@@ -321,10 +322,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("SetIgnoreWait")]
         [HttpPost("SetIgnoreWait")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlaySetIgnoreWait(
+        public async Task<ActionResult> SyncPlaySetIgnoreWait(
             [FromBody, Required] IgnoreWaitRequestDto requestData)
             [FromBody, Required] IgnoreWaitRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new IgnoreWaitGroupRequest(requestData.IgnoreWait);
             var syncPlayRequest = new IgnoreWaitGroupRequest(requestData.IgnoreWait);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -339,10 +340,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("NextItem")]
         [HttpPost("NextItem")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlayNextItem(
+        public async Task<ActionResult> SyncPlayNextItem(
             [FromBody, Required] NextItemRequestDto requestData)
             [FromBody, Required] NextItemRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new NextItemGroupRequest(requestData.PlaylistItemId);
             var syncPlayRequest = new NextItemGroupRequest(requestData.PlaylistItemId);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -357,10 +358,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("PreviousItem")]
         [HttpPost("PreviousItem")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlayPreviousItem(
+        public async Task<ActionResult> SyncPlayPreviousItem(
             [FromBody, Required] PreviousItemRequestDto requestData)
             [FromBody, Required] PreviousItemRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new PreviousItemGroupRequest(requestData.PlaylistItemId);
             var syncPlayRequest = new PreviousItemGroupRequest(requestData.PlaylistItemId);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -375,10 +376,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("SetRepeatMode")]
         [HttpPost("SetRepeatMode")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlaySetRepeatMode(
+        public async Task<ActionResult> SyncPlaySetRepeatMode(
             [FromBody, Required] SetRepeatModeRequestDto requestData)
             [FromBody, Required] SetRepeatModeRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new SetRepeatModeGroupRequest(requestData.Mode);
             var syncPlayRequest = new SetRepeatModeGroupRequest(requestData.Mode);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -393,10 +394,10 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("SetShuffleMode")]
         [HttpPost("SetShuffleMode")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
         [Authorize(Policy = Policies.SyncPlayIsInGroup)]
-        public ActionResult SyncPlaySetShuffleMode(
+        public async Task<ActionResult> SyncPlaySetShuffleMode(
             [FromBody, Required] SetShuffleModeRequestDto requestData)
             [FromBody, Required] SetShuffleModeRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new SetShuffleModeGroupRequest(requestData.Mode);
             var syncPlayRequest = new SetShuffleModeGroupRequest(requestData.Mode);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();
@@ -410,10 +411,10 @@ namespace Jellyfin.Api.Controllers
         /// <returns>A <see cref="NoContentResult"/> indicating success.</returns>
         /// <returns>A <see cref="NoContentResult"/> indicating success.</returns>
         [HttpPost("Ping")]
         [HttpPost("Ping")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
-        public ActionResult SyncPlayPing(
+        public async Task<ActionResult> SyncPlayPing(
             [FromBody, Required] PingRequestDto requestData)
             [FromBody, Required] PingRequestDto requestData)
         {
         {
-            var currentSession = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
+            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
             var syncPlayRequest = new PingGroupRequest(requestData.Ping);
             var syncPlayRequest = new PingGroupRequest(requestData.Ping);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
             return NoContent();
             return NoContent();

+ 11 - 3
Jellyfin.Api/Helpers/RequestHelpers.cs

@@ -1,6 +1,7 @@
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
+using System.Threading.Tasks;
 using Jellyfin.Data.Entities;
 using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
 using Jellyfin.Data.Enums;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Extensions;
@@ -75,17 +76,17 @@ namespace Jellyfin.Api.Helpers
             return true;
             return true;
         }
         }
 
 
-        internal static SessionInfo GetSession(ISessionManager sessionManager, IAuthorizationContext authContext, HttpRequest request)
+        internal static async Task<SessionInfo> GetSession(ISessionManager sessionManager, IAuthorizationContext authContext, HttpRequest request)
         {
         {
             var authorization = authContext.GetAuthorizationInfo(request);
             var authorization = authContext.GetAuthorizationInfo(request);
             var user = authorization.User;
             var user = authorization.User;
-            var session = sessionManager.LogSessionActivity(
+            var session = await sessionManager.LogSessionActivity(
                 authorization.Client,
                 authorization.Client,
                 authorization.Version,
                 authorization.Version,
                 authorization.DeviceId,
                 authorization.DeviceId,
                 authorization.Device,
                 authorization.Device,
                 request.HttpContext.GetNormalizedRemoteIp(),
                 request.HttpContext.GetNormalizedRemoteIp(),
-                user);
+                user).ConfigureAwait(false);
 
 
             if (session == null)
             if (session == null)
             {
             {
@@ -95,6 +96,13 @@ namespace Jellyfin.Api.Helpers
             return session;
             return session;
         }
         }
 
 
+        internal static async Task<string> GetSessionId(ISessionManager sessionManager, IAuthorizationContext authContext, HttpRequest request)
+        {
+            var session = await GetSession(sessionManager, authContext, request).ConfigureAwait(false);
+
+            return session.Id;
+        }
+
         internal static QueryResult<BaseItemDto> CreateQueryResult(
         internal static QueryResult<BaseItemDto> CreateQueryResult(
             QueryResult<(BaseItem, ItemCounts)> result,
             QueryResult<(BaseItem, ItemCounts)> result,
             DtoOptions dtoOptions,
             DtoOptions dtoOptions,

+ 5 - 4
Jellyfin.Server.Implementations/Devices/DeviceManager.cs

@@ -53,12 +53,13 @@ namespace Jellyfin.Server.Implementations.Devices
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />
-        public DeviceOptions? GetDeviceOptions(string deviceId)
+        public async Task<DeviceOptions?> GetDeviceOptions(string deviceId)
         {
         {
-            using var dbContext = _dbProvider.CreateContext();
-            return dbContext.DeviceOptions
+            await using var dbContext = _dbProvider.CreateContext();
+            return await dbContext.DeviceOptions
                 .AsQueryable()
                 .AsQueryable()
-                .FirstOrDefault(d => d.DeviceId == deviceId);
+                .FirstOrDefaultAsync(d => d.DeviceId == deviceId)
+                .ConfigureAwait(false);
         }
         }
 
 
         /// <inheritdoc />
         /// <inheritdoc />

+ 1 - 1
MediaBrowser.Controller/Devices/IDeviceManager.cs

@@ -50,6 +50,6 @@ namespace MediaBrowser.Controller.Devices
 
 
         Task UpdateDeviceOptions(string deviceId, DeviceOptions options);
         Task UpdateDeviceOptions(string deviceId, DeviceOptions options);
 
 
-        DeviceOptions GetDeviceOptions(string deviceId);
+        Task<DeviceOptions> GetDeviceOptions(string deviceId);
     }
     }
 }
 }

+ 5 - 4
MediaBrowser.Controller/Net/ISessionContext.cs

@@ -1,5 +1,6 @@
 #pragma warning disable CS1591
 #pragma warning disable CS1591
 
 
+using System.Threading.Tasks;
 using Jellyfin.Data.Entities;
 using Jellyfin.Data.Entities;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Controller.Session;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
@@ -8,12 +9,12 @@ namespace MediaBrowser.Controller.Net
 {
 {
     public interface ISessionContext
     public interface ISessionContext
     {
     {
-        SessionInfo GetSession(object requestContext);
+        Task<SessionInfo> GetSession(object requestContext);
 
 
-        User GetUser(object requestContext);
+        Task<User> GetUser(object requestContext);
 
 
-        SessionInfo GetSession(HttpContext requestContext);
+        Task<SessionInfo> GetSession(HttpContext requestContext);
 
 
-        User GetUser(HttpContext requestContext);
+        Task<User> GetUser(HttpContext requestContext);
     }
     }
 }
 }

+ 3 - 3
MediaBrowser.Controller/Session/ISessionManager.cs

@@ -80,7 +80,7 @@ namespace MediaBrowser.Controller.Session
         /// <param name="deviceName">Name of the device.</param>
         /// <param name="deviceName">Name of the device.</param>
         /// <param name="remoteEndPoint">The remote end point.</param>
         /// <param name="remoteEndPoint">The remote end point.</param>
         /// <param name="user">The user.</param>
         /// <param name="user">The user.</param>
-        SessionInfo LogSessionActivity(string appName, string appVersion, string deviceId, string deviceName, string remoteEndPoint, Jellyfin.Data.Entities.User user);
+        Task<SessionInfo> LogSessionActivity(string appName, string appVersion, string deviceId, string deviceName, string remoteEndPoint, Jellyfin.Data.Entities.User user);
 
 
         /// <summary>
         /// <summary>
         /// Used to report that a session controller has connected.
         /// Used to report that a session controller has connected.
@@ -313,7 +313,7 @@ namespace MediaBrowser.Controller.Session
         /// <param name="deviceId">The device identifier.</param>
         /// <param name="deviceId">The device identifier.</param>
         /// <param name="remoteEndpoint">The remote endpoint.</param>
         /// <param name="remoteEndpoint">The remote endpoint.</param>
         /// <returns>SessionInfo.</returns>
         /// <returns>SessionInfo.</returns>
-        SessionInfo GetSessionByAuthenticationToken(string token, string deviceId, string remoteEndpoint);
+        Task<SessionInfo> GetSessionByAuthenticationToken(string token, string deviceId, string remoteEndpoint);
 
 
         /// <summary>
         /// <summary>
         /// Gets the session by authentication token.
         /// Gets the session by authentication token.
@@ -323,7 +323,7 @@ namespace MediaBrowser.Controller.Session
         /// <param name="remoteEndpoint">The remote endpoint.</param>
         /// <param name="remoteEndpoint">The remote endpoint.</param>
         /// <param name="appVersion">The application version.</param>
         /// <param name="appVersion">The application version.</param>
         /// <returns>Task&lt;SessionInfo&gt;.</returns>
         /// <returns>Task&lt;SessionInfo&gt;.</returns>
-        SessionInfo GetSessionByAuthenticationToken(AuthenticationInfo info, string deviceId, string remoteEndpoint, string appVersion);
+        Task<SessionInfo> GetSessionByAuthenticationToken(AuthenticationInfo info, string deviceId, string remoteEndpoint, string appVersion);
 
 
         /// <summary>
         /// <summary>
         /// Logouts the specified access token.
         /// Logouts the specified access token.