mirror of https://github.com/OpenVidu/openvidu.git
openvidu-server: concurrent double initialization of single stream recording fix
parent
3374e511ee
commit
f5171c9306
|
@ -17,6 +17,9 @@
|
||||||
|
|
||||||
package io.openvidu.server.core;
|
package io.openvidu.server.core;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
import io.openvidu.server.kurento.endpoint.EndpointType;
|
import io.openvidu.server.kurento.endpoint.EndpointType;
|
||||||
|
@ -41,6 +44,12 @@ public class Participant {
|
||||||
|
|
||||||
private final String METADATA_SEPARATOR = "%/%";
|
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,
|
public Participant(String finalUserId, String participantPrivatetId, String participantPublicId, String sessionId,
|
||||||
Token token, String clientMetadata, GeoLocation location, String platform, EndpointType endpointType,
|
Token token, String clientMetadata, GeoLocation location, String platform, EndpointType endpointType,
|
||||||
Long createdAt) {
|
Long createdAt) {
|
||||||
|
|
|
@ -208,9 +208,20 @@ public class SingleStreamRecordingService extends RecordingService {
|
||||||
|
|
||||||
public void startRecorderEndpointForPublisherEndpoint(final Session session, String recordingId,
|
public void startRecorderEndpointForPublisherEndpoint(final Session session, String recordingId,
|
||||||
MediaProfileSpecType profile, final Participant participant, CountDownLatch globalStartLatch) {
|
MediaProfileSpecType profile, final Participant participant, CountDownLatch globalStartLatch) {
|
||||||
|
|
||||||
log.info("Starting single stream recorder for stream {} in session {}", participant.getPublisherStreamId(),
|
log.info("Starting single stream recorder for stream {} in session {}", participant.getPublisherStreamId(),
|
||||||
session.getSessionId());
|
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) {
|
if (recordingId == null) {
|
||||||
// Stream is being recorded because is a new publisher in an ongoing recorded
|
// 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
|
// 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(),
|
RecorderEndpointWrapper wrapper = new RecorderEndpointWrapper(recorder,
|
||||||
recordingId, participant.getPublisherStreamId(), participant.getClientMetadata(),
|
participant.getParticipantPublicId(), recordingId, participant.getPublisherStreamId(),
|
||||||
participant.getServerMetadata(), kurentoParticipant.getPublisher().getMediaOptions().hasAudio(),
|
participant.getClientMetadata(), participant.getServerMetadata(),
|
||||||
|
kurentoParticipant.getPublisher().getMediaOptions().hasAudio(),
|
||||||
kurentoParticipant.getPublisher().getMediaOptions().hasVideo(),
|
kurentoParticipant.getPublisher().getMediaOptions().hasVideo(),
|
||||||
kurentoParticipant.getPublisher().getMediaOptions().getTypeOfVideo());
|
kurentoParticipant.getPublisher().getMediaOptions().getTypeOfVideo());
|
||||||
|
|
||||||
|
@ -271,6 +283,20 @@ public class SingleStreamRecordingService extends RecordingService {
|
||||||
|
|
||||||
connectAccordingToProfile(kurentoParticipant.getPublisher(), recorder, profile);
|
connectAccordingToProfile(kurentoParticipant.getPublisher(), recorder, profile);
|
||||||
wrapper.getRecorder().record();
|
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,
|
public void stopRecorderEndpointOfPublisherEndpoint(String sessionId, String streamId,
|
||||||
|
|
Loading…
Reference in New Issue