corvus-ch / rabbitmq-cli-consumer

Consume RabbitMQ messages into any cli program
MIT License
236 stars 36 forks source link

Support for rpc pattern - reply_to #55

Open ddegasperi opened 5 years ago

ddegasperi commented 5 years ago

Hi,

I've found this library and find it very useful to run "executables" (but not only php) in a container environment.

In my current case I've to wait for the result of the executable, so I want do a "synchronous" call using the RPC pattern (described in tutorial 6 of the rabbitmq website). I searched the code for clues to the "reply_to" property, but it seems to find no usage.

Probably the best place to publish the "replay_to" message (inc. correlation_id) would be consumer.go after line 108.

Something like the code from the example but only if m.ReplyTo exists:

err = ch.Publish(
    "",        // exchange
    m.ReplyTo, // routing key
    false,     // mandatory
    false,     // immediate
    amqp.Publishing{
            ContentType:   "text/plain",
            CorrelationId: m.CorrelationId,
            Body:          []byte(strconv.Itoa(response)),
    })

Unfortunately, I am not a go programmer and have no experience with this programming language, so I would be very grateful for your help.

corvus-ch commented 5 years ago

The consumer is supposed to be only the initiator. The response to a RPC can and should be send by the executable. At least this is how I have dealt with this requirement myself. This assumes the use of a technology where sending an AMQP message is easy enough to do so.

Will this be an option for you?

ddegasperi commented 5 years ago

Ok, I've wrote a wrapper to read the "reply_to" property and answer to the queue.

Still I think the response if the executable run successfully or failed would be very helpful. Doing so means, adding only the rabbitmq-cli-consumer as container dependency and avoid writing a wrapper foreach usecase.

corvus-ch commented 5 years ago

The example code you provided, only sends the exit code as part of the response body, a hard coded set of message headers and hardcoded assumptions about exchange and other settings. This covers only a very narrow use case. And I am against adding such a limiting feature.

I see that this can be a feature of general interest. In order to make this valuable for a broader audience, the executable would require the means to have control over the response sent. I am open to discuss ideas how this would look like. STDOUT and STDERR are already used for logging. The next thing that comes to mind are pipes with number three and up.

I will think about this and any input will be welcome.

Magentron commented 4 years ago

The previous maintainer had it implemented in his 2.0 branch: https://github.com/ricbra/rabbitmq-cli-consumer/commit/7fa1fa9c8786e45d640bc9164902b17c1a2ec97b Would it be possible to use that to implement RPC support? We need it as well 😉

Magentron commented 4 years ago

Ok, I've wrote a wrapper to read the "reply_to" property and answer to the queue.

@ddegasperi Could you share your code please? Or share how you resolved receiving the response data from the executable?

Magentron commented 4 years ago

File descriptor 3 is not usable since when using the queue:consumer command, the --pipe flag does not work.

I have a basic version working that sends a temporary file path in the headers with the incoming message to the executable and retrieves its response from that temporary file (so the executable has to write the response into it). Obviously, it's not sufficient for a generic solution but it works for me.