-
-
Notifications
You must be signed in to change notification settings - Fork 242
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 race condition when new transports are getting created #47
Conversation
Thanks. This seems interesting. Let please discuss some things before accepting this PR: What would happen in the following scenario?
const remoteSdp = this._remoteSdp.createOfferSdp(
Array.from(this._consumerInfos.values()));
const offer = { type: 'offer', sdp: remoteSdp }; The problem here is that it's using |
BTW, the bug you describe is real, sure. But it should not happen. Please, check
return this._commandQueue.push('addConsumer', { consumer });
But it happens... so there is a bug somewhere. |
Regarding your first comment, you are correct. I think a better solution would be to keep track of the transport state in _setupTransport and if it's already setup just return the resolved promise. something like this: _setupTransport()
{
if (this._pTransport !== null) {
return this._pTransport;
}
logger.debug('_setupTransport()');
this._pTransport = Promise.resolve()
.then(() =>
{
// Get our local DTLS parameters.
const transportLocalParameters = {};
const sdp = this._pc.localDescription.sdp;
const sdpObj = sdpTransform.parse(sdp);
const dtlsParameters = sdpCommonUtils.extractDtlsParameters(sdpObj);
// Let's decide that we'll be DTLS server (because we can).
dtlsParameters.role = 'server';
transportLocalParameters.dtlsParameters = dtlsParameters;
// Provide the remote SDP handler with transport local parameters.
this._remoteSdp.setTransportLocalParameters(transportLocalParameters);
// We need transport remote parameters.
return this.safeEmitAsPromise(
'@needcreatetransport', transportLocalParameters);
})
.then((transportRemoteParameters) =>
{
// Provide the remote SDP handler with transport remote parameters.
this._remoteSdp.setTransportRemoteParameters(transportRemoteParameters);
});
return this._pTransport;
} Regarding your second comment, that also seems correct but we do see the server error quite frequently (although it's quite hard to repro without production traffic). For some background we see the issue most frequently when we have a room with 3+ peers that are producing and 20-30+ peers who are only consuming. |
Hi, as I said in my previous comment, checking any variable within We'll check this issue. However, I've done some tests with the To summarize: this should not happen so there is nothing to add in the handlers code. The |
OK, now I see what you mean with storing The problem here is that, again, this error is supposed to not happen at all since calls to handler methods are enqueued. |
Perfectly fine if you don't want to accept the PR but the promise change I just submitted will ensure that the second consumer gets a properly setup transport. In my above example I left out that _setupTransport always gets called, so if it's been previously called it returns the already resolved promise. |
I know that this PR fixes the problem, but what it worries me is that it should not happen. Have you took a look to the |
I've briefly looked at |
In _handleCommand at line 71 CommandQueue. this._busy is set to false before the queue is shifted. Wouldn't this in rare cases make it possible for another command to swoop in and try to execute the command again before the queue is shifted? |
@havfo since there is only one thread that should not be possible. The event loop won't take up a new task until the end of that block is executed. |
Yes, that line 71 cannot be wrong. Guys, yesterday I did some tests with the Thanks! |
Hi, here the test app I've done. I cannot reproduce the issue here in any way. But I would like more eyes on this code. May be it's not good enough to reproduce what it happens in real life when using mediasoup-client: |
Let's please handle this issue in #48. I've some news in there. |
Closing as the result of #48. |
Every so often we would see "Transport with same transportId already exists". Tracked it down to when we a user joined a room with multiple existing consumers. There is a race condition where _setupTransport was getting called multiple times. This PR adds some state to protect against calling _setupTransport multiple times.