public async Task <Unit> Handle(TalkingStickPassRequest request, CancellationToken cancellationToken) { var(participant, roomId, failIfHasSpeaker) = request; await using (await _repository.LockRoom(participant.ConferenceId, roomId)) { await _mediator.Send(new ClearCacheRequest()); if (failIfHasSpeaker) { var currentSpeaker = await _repository.GetCurrentSpeaker(participant.ConferenceId, roomId); if (currentSpeaker != null) { throw SceneError.AlreadyHasSpeaker.ToException(); } } if (!await CheckParticipantIsInRoom(participant, roomId)) { throw new ParticipantNotFoundException(participant); } await _repository.SetCurrentSpeakerAndRemoveFromQueue(participant, roomId); await _modeHandler.InvalidateTalkingSceneWithLockAcquired(participant.ConferenceId, roomId); } await _mediator.Send(new UpdateSynchronizedObjectRequest(participant.ConferenceId, SynchronizedSceneTalkingStick.SyncObjId(roomId))); return(Unit.Value); }
private async ValueTask ElectNewCurrentSpeaker(string conferenceId, string roomId, SynchronizedRooms rooms, TalkingStickMode mode) { if (mode == TalkingStickMode.Queue) { var nextSpeaker = await _repository.Dequeue(conferenceId, roomId); if (nextSpeaker == null) { return; } if (!CheckParticipantIsInRoom(nextSpeaker.Value, roomId, rooms)) { await ElectNewCurrentSpeaker(conferenceId, roomId, rooms, mode); return; } await _repository.SetCurrentSpeakerAndRemoveFromQueue(nextSpeaker.Value, roomId); } }