Skip to content
This repository was archived by the owner on Dec 14, 2020. It is now read-only.
This repository was archived by the owner on Dec 14, 2020. It is now read-only.

Asynchronous Send mode. #179

@alanconway

Description

@alanconway

The current Sender.Send() blocks for the remote disposition. This is fine for many applications, but it does not allow sending at full network throughput because it forces the sender t idle for at least 2x the network latency between each send.

The doc mentions using goroutines, but this is not really workable - you lose control of message ordering. What you really want is an ordered stream of messages going out and an independent ordered stream of dispositions coming in.

One solution is to send the dispositions back on a channel, like https://github.com/apache/qpid-proton/blob/go1/electron/sender.go#L61

However I am currently leaning towards a design like this:

Sender {  AsyncSend(Message) Result }
Result { Wait() error }

For the sync case this is almost as easy to use as blocking Send():

    err := AsyncSend(Message).Wait()

and it supports the the channel solution for async:

    type myResult struct { r: Result; extra: ...}
    myResults := make(chan myResult, n)
    go func() { ... ; myResults <- myResult{r: s.AsyncSend(m), extra: ...} ...}() 
    go func() { for r := range(myResults) { if err := r.r.Wait() {boom()} else { proces(r.extra)}})()

I'd like to hear comments on the design before I submit a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions