Repository navigation
Data tracks: subscribing - #992
Conversation
ce38d1d to
a1d1643
Compare
a1d1643 to
bee8224
Compare
bee8224 to
2fd1c9b
Compare
There was a problem hiding this comment.
Note
Newer findings are available below. Devin Review posted a newer report on this PR, in addition to the findings presented here.
Devin Review found 5 potential issues.
2 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)
| // Subscribe, without stalling signal handling. | ||
| func (t remoteDataTrackTransport) OnTrackPublished(track *datatrack.RemoteTrack) { | ||
| rp := t.room.GetParticipantByIdentity(track.PublisherIdentity()) | ||
| go func() { |
There was a problem hiding this comment.
🟡 Publication callbacks arrive reversed
Each event starts an independent goroutine, so rapid publication and removal can run OnDataTrackUnpublished first. Applications observe removal before discovery or subscribe after removal.
Prompt for agents
Dispatch data-track lifecycle callbacks asynchronously but in publication order. The two remoteDataTrackTransport methods currently launch independent goroutines, allowing publish and unpublish events for the same track to overtake each other. Use a serialized room-level or per-track callback queue that does not block signal handling, while retaining participant-before-room callback ordering.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Valid concern. Am guessing the media track has the same pattern?
2fd1c9b to
b7920b9
Compare
b7920b9 to
282a381
Compare
9b0d4c1 to
95db271
Compare
95db271 to
f187427
Compare
There was a problem hiding this comment.
Devin Review found 1 new potential issue.
4 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)
cnderrauber
left a comment
There was a problem hiding this comment.
Looks good, thank you!
boks1971
left a comment
There was a problem hiding this comment.
I have not reviewed remote.go and remote_test.go yet. But, I am stopping here for some comments and pick it up later after your response.
Some notes
- I think
remoteDataTracksshould be distributed inRemoteParticipantif possible. It should just follow the media track pattern. At room level, I don't think it should be dealing with tracks. It should be dealing with only participants and tracks should live at participant. We should look at it more closely if that is not possible for some reason (I left the same comment in the publish PR where local tracks if possible should be managed inside theLocalParticipant) - Because I have not fully ready the above files, I am not sure of the
RemoteManager(and similarlyLocalManager's roles). But for abstraction and making things private, you can do something like
type RemoteManager interface {
// only publicly needed methods here
}
type remoteManager struct {
// the implementation which is package private
}
var _ RemoteManager = (*remoteManager)(nil) // compiler trick to ensure that remoteManager implements the RemoteManager interface.
func NewRemoteManager() RemoteManager{
}
| callback := &lksdk.RoomCallback{ | ||
| ParticipantCallback: lksdk.ParticipantCallback{ | ||
| OnDataTrackPublished: func(track *datatrack.RemoteTrack, rp *lksdk.RemoteParticipant) { | ||
| subscribe(ctx, track) |
There was a problem hiding this comment.
I do not remember if all these callbacks can happen in the same goroutine. If so, doing go subscribe would be the right thing to ensure that subscribes are spawned off to their own goroutine and callbacks do not block.
There was a problem hiding this comment.
It looks like for media tracks OnTrackPublished/OnTrackUnpublished are invoked synchronously on the signal goroutine (see remoteparticipant.go). Should we do the same here?
There was a problem hiding this comment.
Yeah, that should be fine, but also depends on what the callbacks do. Those are emitted to the app. This one is doing some internal operation. Just have to make sure that it does not block. Sending it synchronously to app level is probably more risky potentially, but it is existing. I think synchronous should be fine, but just wanted to flag.
| // Subscribe, without stalling signal handling. | ||
| func (t remoteDataTrackTransport) OnTrackPublished(track *datatrack.RemoteTrack) { | ||
| rp := t.room.GetParticipantByIdentity(track.PublisherIdentity()) | ||
| go func() { |
There was a problem hiding this comment.
Valid concern. Am guessing the media track has the same pattern?
1ab44ed to
da6b831
Compare
262c34b to
4441c27
Compare
9919be6 to
3944765
Compare
Fixes `TestDataTrack_SubscriberSideFault/full_reconnect` E2E case
Adds support for subscribing to data tracks.
Architecture and public API closely match Rust and JS clients:
OnDataTrackPublishedevent to receive the track object which they can then use to subscribe if desired.RemoteManageris owned by the room to manage internal state and transitions for all remote data tracks.Closes BOT-541