Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(breakout-rooms): Fixes the case where a single participant switches to breakout room. #1169

Merged
merged 3 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import org.jitsi.xmpp.extensions.jingle.*;

import org.jitsi.xmpp.extensions.jitsimeet.*;
import org.jitsi.jicofo.jigasi.*;
import org.jitsi.jicofo.jibri.*;

import org.jitsi.xmpp.extensions.visitors.*;
Expand Down Expand Up @@ -72,6 +71,12 @@
public class JitsiMeetConferenceImpl
implements JitsiMeetConference, XmppProvider.Listener
{

/**
* Status used by participants when they are switching from a room to a breakout room.
*/
private static final String BREAKOUT_SWITCHING_STATUS = "switch_room";

/**
* Name of MUC room that is hosting Jitsi Meet conference.
*/
Expand Down Expand Up @@ -164,7 +169,9 @@ public class JitsiMeetConferenceImpl
private Future<?> singleParticipantTout;

/**
* A task to stop the conference if no participants join after an initial timeout.
* A task to stop the conference if no participants or breakout rooms are present after a timeout.
* It's triggered when the conference is first created, or when the last participant leaves with an indication
* that it will join a breakout room.
*/
private Future<?> conferenceStartTimeout;

Expand Down Expand Up @@ -276,18 +283,7 @@ public JitsiMeetConferenceImpl(
this.jicofoServices = jicofoServices;
this.jvbVersion = jvbVersion;

conferenceStartTimeout = TaskPools.getScheduledPool().schedule(
() ->
{
if (includeInStatistics)
{
logger.info("Expiring due to initial timeout.");
}
stop();
},
ConferenceConfig.config.getConferenceStartTimeout().toMillis(),
TimeUnit.MILLISECONDS);

rescheduleConferenceStartTimeout();

visitorCodecs = new PreferenceAggregator(
logger,
Expand Down Expand Up @@ -971,13 +967,14 @@ else if (participants.size() == 0)
}
}

maybeStop();
maybeStop(chatRoomMember);
}

/**
* Stop the conference if there are no members and there are no associated breakout room.
* @param chatRoomMember The participant leaving if any.
*/
private void maybeStop()
private void maybeStop(ChatRoomMember chatRoomMember)
{
ChatRoom chatRoom = this.chatRoom;
if (chatRoom == null || chatRoom.getMemberCount() == 0)
Expand All @@ -986,6 +983,13 @@ private void maybeStop()
{
logger.info("Breakout rooms still present, will not stop.");
}
else if (chatRoomMember != null
&& chatRoomMember.getPresence() != null
&& BREAKOUT_SWITCHING_STATUS.equals(chatRoomMember.getPresence().getStatus()))
{
logger.info("Member moving to breakout room, will not stop.");
rescheduleConferenceStartTimeout();
}
else
{
logger.info("Last member left, stopping.");
Expand All @@ -999,7 +1003,7 @@ private void maybeStop()
*/
public void breakoutConferenceEnded()
{
maybeStop();
maybeStop(null);
}

@Override
Expand Down Expand Up @@ -2072,6 +2076,32 @@ private void rescheduleSingleParticipantTimeout()
logger.info("Scheduled single person timeout.");
}

/**
* (Re)schedules conference start timeout.
*/
private void rescheduleConferenceStartTimeout()
{
conferenceStartTimeout = TaskPools.getScheduledPool().schedule(
() ->
{
if (includeInStatistics)
{
logger.info("Expiring due to initial timeout.");
}

// in case of last participant leaving to join a breakout room, we want to skip destroy
if (jicofoServices.getFocusManager().hasBreakoutRooms(roomName))
{
logger.info("Breakout rooms present, will not stop.");
return;
}

stop();
},
ConferenceConfig.config.getConferenceStartTimeout().toMillis(),
TimeUnit.MILLISECONDS);
}

/** Called when a new visitor has been added to the conference. */
private void visitorAdded(List<String> codecs)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class MockChatRoom(val xmppProvider: XmppProvider) {
every { features } returns Features.defaultFeatures
every { debugState } returns OrderedJsonObject()
every { presence } returns mockk {
every { status } returns null
every { getExtension(any<String>()) } returns null
every { getExtension(any<QName>()) } returns null
every { getExtension(any<Class<out ExtensionElement>>()) } returns null
Expand Down
Loading