Join GitHub today
When is an IceGatherer allowed to prune host, reflexive and relay candidates? #174
I personally prefer solution (a) or (b). The good thing about (a) is that the IceGatherer will prune at some point if nothing is done and can also be extended and the remote side can be guarantee a timeframe for which received candidates are valid. But (a) also has a bad point of not being able to prune at absolute time points (although gather() with immediate timeout would accomplish this). The API surface would require IceGatherer.gather() to accept an optional timeout parameter.
Solution (b) allows for absolute control of when IceGatherer candidates can be pruned but pruning requires active intervention or candidates will remain needlessly "hot". The API surface would need an additional IceGatherer.prune() method.
Solution (c) is beneficial that the API surface is not expanded. The drawback is that it feels like a bit of a hack to keep an IceTransport alive for the sake of keeping candidates "hot" [although that is debatable]. The larger drawback is that it's unclear when an IceTransport is truly complete unless we add a "this is the final remote candidate expected [for now]" notification to the IceTransport so it can know that it's now safe to prune candidates. Another draw back would be that an IceTransport object might not be immediately disposed because of garbage collection nor would necessarily an IceTransport.stop() be called if a IceTransport.start() was never called in the first place.
[will be cross posted to ORTC CG email list so please reply there]
This was referenced
Feb 7, 2015
In Section 5.3, add the timeout attribute to the constructor and interface as follows:
[Constructor(RTCIceGatherOptions options, optional unsigned long timeout)]
timeout of type unsigned long, readonly
pushed a commit
Mar 25, 2015
I like Option A, but I could live with Option B.
I don't think a reference counting solution (like B) will work properly but there is another option that could work. I know that a non-started Transport could hold a reference to all candidates so effectively Option B can behave like option A but the principle of reference counting on started transports seems problematic.
The local IceTransport may receive trickled remote host candidates that might all fail, thus the local IceTransport might assume there's no reason to keep warm any reflexive/relay candidates (since all known pairing fail). The local IceGatherer could therefor incorrectly assume that no reflexive/relay candidates are needed. But later some remote reflexive / relay candidates can trickle in causing valid pairings with local reflexive/relay candidates. Unfortunately the gather might have pruned those already due to not being referenced. The local IceTransport has no way to know if more remote candidates are still pending to keep local gatherer reflexive/relay candidates valid. The only way it could work is that the candidates are kept "warm" while an RTCIceTransport is not in the completed state and not related to the reference counting in the candidate pairing.
So option A works but the downside to A is that reflexive/relay candidates will be kept "warm" until the programmer does something.
Option B can only work if we base the candidates being kept alive on a transport being attached which is not in the "completed" state rather than doing candidate pair reference counting. We currently have no way to associate a non-started transport (i.e. absent remote parameters) with a gather so we would need to add that to the transport constructor.
Option C - have a timeout mechanism where the gatherer is kept warm for a period of time and unused candidates can be pruned after that timeout. Thus a programmer would not need to do anything and a reasonable (configurable) timeout will prune out non used candidates. The option to renew could be calling a "gather()" method again to extend the timeout longer or prune earlier (e.g. immediately).
Now in further thought, I like option B best if we:
I think that would make the behaviour clear and there would be a clear point in which the candidates are to be pruned. This does not solve the "respond to incoming connectivity checks early" problem #170 .
If the IceGatherer is added to the constructor, is this optional (as Peter suggested) or required? If required (which would seem to be needed to track all iceTransport(s) associated with an IceGatherer), do we need iceTransport.createAssociatedTransport(RTCIceGatherer gatherer)?
In Section 3.3.1 modify the text to:
Add to Section 5.1: