I'm using the pion/webrtc Go library in my project and found this problem that the callback-based API the library provides (which mirrors the JavaScript API of WebRTC) can be awkward to use in Go.
For example, doing the following
conn.OnTrack(func(...) { ... })
conn.OnICEConnectionStateChange(func(...) { ... })
is typical in JavaScript, but in Go, this has a few problems:
- This API makes it easy to introduce data race, if the callbacks are called in parallel.
- The callback-based API propagates to other part of the codebase and makes everything takes callbacks.
What's the conventional way to handle this situation in Go? I'm new to Go and I read that synchronous API is preferred in Go because Goroutines are cheap. So perhaps one possible design is to use a channel to synchronize the callbacks:
msgChan := make(chan Msg)
// or use a separate channel for each type of event?
conn.OnTrack(func(...) {
msgChan <- onTrackMsg
})
conn.OnICEConnectionStateChange(func(...) {
msgChan <- onStateChangeMsg
})
for {
msg := <-msgChan
// do something depending on the type of msg
}
I think forcing synchronization with channels basically mimics the single-threaded nature of JavaScript.
Anyway, how do people usually model event-driven workflow in Go?
Aucun commentaire:
Enregistrer un commentaire