Open stevvooe opened 9 years ago
My thoughts on this and general synchronization is mostly about how acks would need to work. To get normal channel behavior (without select), a single ack is needed to be sent by the receiver to allow the sender to unblock. To implement channels with select, a double ack would be needed to unblock the sender, and then the receiver. I think it would be worth exploring if this pattern can be achieved without changing the underlying protocol, and if not, whether the underlying protocol can be changed without changing the core interface. Changing the core interface is not an option, but adding tools, utilities, and better constructors is certainly worth exploring. Can you also come up with a more concrete example? Otherwise I will tag and just let sit.
I must be missing something. Isn't the double ack only necessary for channels with capacity 0? Also, t's not really double-ack, just that the receiver has to send a request-for-message and then receives the message in the reply... Sounds very inefficient over a network, doesn't seem like a good network pattern...
This is really similar to how errors need to be forwarded through Channel. If there are tree parties connected by channels, where A is the sender, B is a generic proxy and C is the actual service:
A --> B --> C
^ |
|-----------|
(sorry for the bad ASCII art)
ACKs will be needed to send over any network error B is facing when contacting C. The current semantic for messages over channels is 'fire and forget'.
@tve anything that we want to guarantee at single process level needs to work with an unlimited numbers of parties involved.
To me @dmcgowan is describing sounds a lot like the 'best effort', 'at least once', and 'at most once' messaging guarantees. A really nice way of describing it is defined in the MQTT 3.1.1 spec QoS section.
Most of the power of Go channels come from flexibility provided by select clauses and the analogous
reflect
package API. An efficient select functionality inlibchan
would bring it further into parity with Go channels and could support some powerful use cases:An implementation could be as simple as providing a select call that spawns multiple goroutines for each sender and receiver passed in and dispatches a callback based on it. More complex implementations would add methods to
Sender
andReceiver
that indicate whether the operation can proceed. It may make sense to even bridge it with process-local Go channels. The API could take hints from thereflect
package channel API.