openvidu-server: concurrent double initialization of single stream recording fix

pull/494/head
pabloFuente 2020-05-23 22:45:42 +02:00
parent 3374e511ee
commit f5171c9306
2 changed files with 92 additions and 57 deletions

View File

@ -17,6 +17,9 @@
package io.openvidu.server.core;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import com.google.gson.JsonObject;
import io.openvidu.server.kurento.endpoint.EndpointType;
@ -41,6 +44,12 @@ public class Participant {
private final String METADATA_SEPARATOR = "%/%";
/**
* This lock protects the initialization of a RecorderEndpoint when INDIVIDUAL
* recording
*/
public Lock singleRecordingLock = new ReentrantLock();
public Participant(String finalUserId, String participantPrivatetId, String participantPublicId, String sessionId,
Token token, String clientMetadata, GeoLocation location, String platform, EndpointType endpointType,
Long createdAt) {

View File

@ -208,9 +208,20 @@ public class SingleStreamRecordingService extends RecordingService {
public void startRecorderEndpointForPublisherEndpoint(final Session session, String recordingId,
MediaProfileSpecType profile, final Participant participant, CountDownLatch globalStartLatch) {
log.info("Starting single stream recorder for stream {} in session {}", participant.getPublisherStreamId(),
session.getSessionId());
try {
if (participant.singleRecordingLock.tryLock(15, TimeUnit.SECONDS)) {
try {
if (this.activeRecorders.get(session.getSessionId())
.containsKey(participant.getPublisherStreamId())) {
log.warn("Concurrent initialization of RecorderEndpoint for stream {} of session {}. Returning",
participant.getPublisherStreamId(), session.getSessionId());
return;
}
if (recordingId == null) {
// Stream is being recorded because is a new publisher in an ongoing recorded
// session. If recordingId is defined is because Stream is being recorded from
@ -260,9 +271,10 @@ public class SingleStreamRecordingService extends RecordingService {
}
});
RecorderEndpointWrapper wrapper = new RecorderEndpointWrapper(recorder, participant.getParticipantPublicId(),
recordingId, participant.getPublisherStreamId(), participant.getClientMetadata(),
participant.getServerMetadata(), kurentoParticipant.getPublisher().getMediaOptions().hasAudio(),
RecorderEndpointWrapper wrapper = new RecorderEndpointWrapper(recorder,
participant.getParticipantPublicId(), recordingId, participant.getPublisherStreamId(),
participant.getClientMetadata(), participant.getServerMetadata(),
kurentoParticipant.getPublisher().getMediaOptions().hasAudio(),
kurentoParticipant.getPublisher().getMediaOptions().hasVideo(),
kurentoParticipant.getPublisher().getMediaOptions().getTypeOfVideo());
@ -271,6 +283,20 @@ public class SingleStreamRecordingService extends RecordingService {
connectAccordingToProfile(kurentoParticipant.getPublisher(), recorder, profile);
wrapper.getRecorder().record();
} finally {
participant.singleRecordingLock.unlock();
}
} else {
log.error(
"Timeout waiting for individual recording lock to be available for participant {} of session {}",
participant.getParticipantPublicId(), session.getSessionId());
}
} catch (InterruptedException e) {
log.error(
"InterruptedException waiting for individual recording lock to be available for participant {} of session {}",
participant.getParticipantPublicId(), session.getSessionId());
}
}
public void stopRecorderEndpointOfPublisherEndpoint(String sessionId, String streamId,