예제 #1
0
        /// <inheritdoc />
        public void NewGroup(SessionInfo session, NewGroupRequest request, CancellationToken cancellationToken)
        {
            if (session == null)
            {
                throw new InvalidOperationException("Session is null!");
            }

            if (request == null)
            {
                throw new InvalidOperationException("Request is null!");
            }

            // Locking required to access list of groups.
            lock (_groupsLock)
            {
                // Make sure that session has not joined another group.
                if (_sessionToGroupMap.ContainsKey(session.Id))
                {
                    var leaveGroupRequest = new LeaveGroupRequest();
                    LeaveGroup(session, leaveGroupRequest, cancellationToken);
                }

                var group = new Group(_loggerFactory, _userManager, _sessionManager, _libraryManager);
                _groups[group.GroupId] = group;

                if (!_sessionToGroupMap.TryAdd(session.Id, group))
                {
                    throw new InvalidOperationException("Could not add session to group!");
                }

                UpdateSessionsCounter(session.UserId, 1);
                group.CreateGroup(session, request, cancellationToken);
            }
        }
예제 #2
0
        public void LeaveGroupRequest(
            [Values("test", "a groupId")] string groupId,
            [Values("", "an existing member")] string memberId)
        {
            var request = new LeaveGroupRequest(groupId, memberId);

            request.AssertCanEncodeDecodeRequest(0);
        }
예제 #3
0
        public ActionResult SyncPlayLeaveGroup()
        {
            var currentSession  = RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request);
            var syncPlayRequest = new LeaveGroupRequest();

            _syncPlayManager.LeaveGroup(currentSession, syncPlayRequest, CancellationToken.None);
            return(NoContent());
        }
예제 #4
0
        public async Task <ActionResult> SyncPlayLeaveGroup()
        {
            var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);

            var syncPlayRequest = new LeaveGroupRequest();

            _syncPlayManager.LeaveGroup(currentSession, syncPlayRequest, CancellationToken.None);
            return(NoContent());
        }
예제 #5
0
        public async Task <IActionResult> LeaveGroup([FromQuery] LeaveGroupRequest request)
        {
            var response = await mediator.Send(request);

            logger.LogResponse($"User #{HttpContext.GetCurrentUserId()} leaved group #{request.GroupId}",
                               response.Error);

            return(this.CreateResponse(response));
        }
예제 #6
0
        private void OnSessionEnded(object sender, SessionEventArgs e)
        {
            var session = e.SessionInfo;

            if (_sessionToGroupMap.TryGetValue(session.Id, out var group))
            {
                var leaveGroupRequest = new LeaveGroupRequest();
                LeaveGroup(session, leaveGroupRequest, CancellationToken.None);
            }
        }
 public LeaveGroupResponse LeaveGroup(ISession session, LeaveGroupRequest request)
 {
     KickParticipants(session, new KickParticipantsRequest {
         GroupId = request.GroupId, ParticipantIds = new List <long>()
         {
             session.UserId
         }
     });
     return(request.CreateResponse <LeaveGroupResponse>());
 }
예제 #8
0
        /// <inheritdoc />
        public void LeaveGroup(SessionInfo session, LeaveGroupRequest request, CancellationToken cancellationToken)
        {
            if (session == null)
            {
                throw new InvalidOperationException("Session is null!");
            }

            if (request == null)
            {
                throw new InvalidOperationException("Request is null!");
            }

            // Locking required to access list of groups.
            lock (_groupsLock)
            {
                if (_sessionToGroupMap.TryGetValue(session.Id, out var group))
                {
                    // Group lock required to let other requests end first.
                    lock (group)
                    {
                        if (_sessionToGroupMap.TryRemove(session.Id, out var tempGroup))
                        {
                            if (!tempGroup.GroupId.Equals(group.GroupId))
                            {
                                throw new InvalidOperationException("Session was in wrong group!");
                            }
                        }
                        else
                        {
                            throw new InvalidOperationException("Could not remove session from group!");
                        }

                        UpdateSessionsCounter(session.UserId, -1);
                        group.SessionLeave(session, request, cancellationToken);

                        if (group.IsGroupEmpty())
                        {
                            _logger.LogInformation("Group {GroupId} is empty, removing it.", group.GroupId);
                            _groups.Remove(group.GroupId, out _);
                        }
                    }
                }
                else
                {
                    _logger.LogWarning("Session {SessionId} does not belong to any group.", session.Id);

                    var error = new GroupUpdate <string>(Guid.Empty, GroupUpdateType.NotInGroup, string.Empty);
                    _sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None);
                    return;
                }
            }
        }
예제 #9
0
        public async Task DisposeAsync()
        {
            if (Interlocked.Increment(ref _disposeCount) != 1)
            {
                await _disposePromise.Task;
                return;
            }

            try {
                Router.Log.Debug(() => LogEvent.Create($"Disposing Consumer {{GroupId:{GroupId},MemberId:{MemberId}}}"));
                _disposeToken.Cancel();
                _fetchSemaphore.Dispose();
                _joinSemaphore.Dispose();
                _syncSemaphore.Dispose();

                try {
                    var batches = Interlocked.Exchange(ref _batches, ImmutableDictionary <TopicPartition, IMessageBatch> .Empty);
                    await Task.WhenAll(batches.Values.Select(b => b.CommitMarkedAsync(CancellationToken.None))).ConfigureAwait(false);

                    foreach (var batch in batches.Values)
                    {
                        batch.Dispose();
                    }
                } catch (Exception ex) {
                    Router.Log.Info(() => LogEvent.Create(ex));
                }
                _assignment = null;

                try {
                    await Task.WhenAny(_heartbeatTask, _stateChangeTask, Task.Delay(TimeSpan.FromSeconds(1), CancellationToken.None)).ConfigureAwait(false);

                    if (_leaveOnDispose)
                    {
                        var request = new LeaveGroupRequest(GroupId, MemberId);
                        await Router.SendAsync(request, GroupId, CancellationToken.None, retryPolicy : Retry.None).ConfigureAwait(false);
                    }
                } catch (Exception ex) {
                    Router.Log.Info(() => LogEvent.Create(ex));
                }

                if (!_leaveRouterOpen)
                {
                    await Router.DisposeAsync();
                }
                _disposeToken.Dispose();
            } finally {
                _disposePromise.TrySetResult(true);
            }
        }
예제 #10
0
        public LeaveGroupResponse LeaveGroup()
        {
            if (String.IsNullOrWhiteSpace(_memberId))
            {
                throw new InvalidOperationException();
            }
            var request  = new LeaveGroupRequest(_groupId, _memberId);
            var response = (LeaveGroupResponse)_client.SubmitRequest(_coordinateBroker, request);

            Trace.TraceInformation("{0:HH:mm:ss.fff} [{1:d2}] #6 Member '{2}' leave group '{3}'",
                                   DateTime.Now, Thread.CurrentThread.ManagedThreadId, _memberId, _groupId);
            _heartbeatTimer.Change(Timeout.Infinite, Timeout.Infinite);
            response.TryThrowFirstErrorOccured();
            return(response);
        }
예제 #11
0
        public void LeaveGroupRequest()
        {
            var request = new LeaveGroupRequest();

            request.GroupId  = Guid.NewGuid().ToString();
            request.MemberId = Guid.NewGuid().ToString();

            Stream binary1 = new MemoryStream();

            request.Serialize(binary1);

            binary1.Seek(0L, SeekOrigin.Begin);
            var request2 = new LeaveGroupRequest();

            request2.Deserialize(binary1);

            var compareLogic = new CompareLogic();
            var result       = compareLogic.Compare(request, request2);

            Assert.True(result.AreEqual);

            Stream binary2 = new MemoryStream();

            request.Serialize(binary2);
            Assert.Equal(binary1.Length, binary2.Length);

            using (var stream1 = new MemoryStream())
                using (var stream2 = new MemoryStream()) {
                    binary1.Seek(0L, SeekOrigin.Begin);
                    binary1.CopyTo(stream1);

                    binary2.Seek(0L, SeekOrigin.Begin);
                    binary2.CopyTo(stream2);

                    Assert.Equal(stream1.Length, stream2.Length);
                    stream1.Seek(0L, SeekOrigin.Begin);
                    var bytes1 = stream1.ToArray();

                    stream2.Seek(0L, SeekOrigin.Begin);
                    var bytes2 = stream2.ToArray();
                    Assert.Equal(bytes1.Length, bytes2.Length);

                    for (int i = 0; i < bytes1.Length; i++)
                    {
                        Assert.Equal(bytes1[i], bytes2[i]);
                    }
                }
        }
예제 #12
0
        public async override Task <LeaveGroupResponse> LeaveGroup(LeaveGroupRequest request, ServerCallContext context)
        {
            try
            {
                var result = new LeaveGroupResponse {
                    Success = true
                };
                var userIdentifier = GetUserIdentifier(context);
                var user           = await _groupStore.GetUser(userIdentifier);

                if (user != null)
                {
                    var userGroup = await _groupStore.GetUserGroup(user.Id, request.Id);

                    if (userGroup != null)
                    {
                        await _groupStore.RemoveUserGroup(userGroup);
                    }
                    else
                    {
                        result.Success = false;
                        result.Message = "User is not connected to group";
                    }
                }
                else
                {
                    result.Success = false;
                    result.Message = "User does not exist";
                }
                return(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                return(new LeaveGroupResponse
                {
                    Success = false,
                    Message = ex.Message
                });
            }
        }
예제 #13
0
        /// <inheritdoc />
        public void JoinGroup(SessionInfo session, JoinGroupRequest request, CancellationToken cancellationToken)
        {
            if (session == null)
            {
                throw new InvalidOperationException("Session is null!");
            }

            if (request == null)
            {
                throw new InvalidOperationException("Request is null!");
            }

            var user = _userManager.GetUserById(session.UserId);

            // Locking required to access list of groups.
            lock (_groupsLock)
            {
                _groups.TryGetValue(request.GroupId, out Group group);

                if (group == null)
                {
                    _logger.LogWarning("Session {SessionId} tried to join group {GroupId} that does not exist.", session.Id, request.GroupId);

                    var error = new GroupUpdate <string>(Guid.Empty, GroupUpdateType.GroupDoesNotExist, string.Empty);
                    _sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None);
                    return;
                }

                // Group lock required to let other requests end first.
                lock (group)
                {
                    if (!group.HasAccessToPlayQueue(user))
                    {
                        _logger.LogWarning("Session {SessionId} tried to join group {GroupId} but does not have access to some content of the playing queue.", session.Id, group.GroupId.ToString());

                        var error = new GroupUpdate <string>(group.GroupId, GroupUpdateType.LibraryAccessDenied, string.Empty);
                        _sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None);
                        return;
                    }

                    if (_sessionToGroupMap.TryGetValue(session.Id, out var existingGroup))
                    {
                        if (existingGroup.GroupId.Equals(request.GroupId))
                        {
                            // Restore session.
                            UpdateSessionsCounter(session.UserId, 1);
                            group.SessionJoin(session, request, cancellationToken);
                            return;
                        }

                        var leaveGroupRequest = new LeaveGroupRequest();
                        LeaveGroup(session, leaveGroupRequest, cancellationToken);
                    }

                    if (!_sessionToGroupMap.TryAdd(session.Id, group))
                    {
                        throw new InvalidOperationException("Could not add session to group!");
                    }

                    UpdateSessionsCounter(session.UserId, 1);
                    group.SessionJoin(session, request, cancellationToken);
                }
            }
        }
예제 #14
0
 public async Task <IActionResult> LeaveGroup(LeaveGroupRequest request, [FromServices] IHandler <LeaveGroupRequest, ObjectResult> handler)
 {
     return(await handler.Handle(request));
 }
예제 #15
0
 public Task <LeaveGroupResponse> LeaveGroup(LeaveGroupRequest request)
 {
     return(_connectionManager.SendRequestAndWaitResponse <LeaveGroupResponse>(request));
 }