Class DefaultPublisher<T>
- Type Parameters:
T- payload type
- All Implemented Interfaces:
AutoCloseable,Publisher<T>
Three things are non-negotiable here, because each is a way messages get lost quietly: the publish waits for a confirm, an unroutable message is an error rather than a shrug, and the envelope is stamped onto the message so the consumer can tell what it received.
Choosing a format
A publisher writes one format, chosen when it is built:
Publisher<Order> orders = mq.publisher("orders", "order.placed", Order.class); // JSON
Publisher<Order> legacy = mq.publisher("legacy", "order", Order.class).asXml();
Publisher<byte[]> files = mq.publisher("files", "file.new", byte[].class).asBytes();
Publisher<Order> avro = mq.publisher("events", "order", Order.class).as(new AvroCodec(registry));
Chosen at the publisher rather than per message, and that is a decision rather than an
omission. A queue whose messages are sometimes JSON and sometimes XML is a queue nobody can
write a consumer against, so the useful place to decide is once, where the destination is
named. It also has to be here for a duller reason: by the time send has returned there
is nothing left to choose, because the message is already at the broker.
-
Method Summary
Modifier and TypeMethodDescriptionThe same destination, written in a named format.The same destination, written with a codec of the caller's own.asBytes()asJson()asText()asXml()asYaml()voidclose()codec()options()replyingTo(String replyQueue) Names the queue a reply to this message should be sent to.Publishes a message and waits for the broker to confirm it.Publishes a message built on an explicit envelope.sendAll(Collection<? extends T> payloads) Publishes a batch and waits for every confirm.Publishes without waiting for the broker to confirm.Publishes without waiting, with an envelope of your own.toString()with(PublishOptions options) The same destination, published differently.
-
Method Details
-
replyingTo
Names the queue a reply to this message should be sent to.Used by
Requester; publishing this by hand means taking on the correlation and the timeout yourself, which is whatRequesterexists to avoid.- Parameters:
replyQueue- queue the responder should answer on- Returns:
- a publisher that asks for a reply
-
with
The same destination, published differently.A new publisher rather than a mutated one, for the same reason
as(Codec)is: two threads sharing a publisher must not have its behaviour changed underneath them.- Parameters:
options- how these messages should be published- Returns:
- a publisher using those options; this one is left alone
-
options
- Returns:
- how this publisher publishes
-
as
The same destination, written in a named format.- Parameters:
format- short format name, such asjsonorxml- Returns:
- a publisher writing that format; this one is left alone
- Throws:
AceMqException- if no module on the classpath provides that format
-
as
The same destination, written with a codec of the caller's own.How a format AceMQ does not ship is used: implement
Codecand pass it. Avro and Protobuf belong here rather than behind a name of their own, because neither can be built without a schema and a method taking no arguments would only be able to fail.- Parameters:
format- the codec to write with- Returns:
- a publisher writing that format; this one is left alone
-
asJson
- Returns:
- the same destination, written as JSON; what a publisher does anyway unless the connection was given a different codec
-
asXml
- Returns:
- the same destination, written as XML
- Throws:
AceMqException- unless org.acemq:acemq-amqp-codec-xml is on the classpath
-
asYaml
- Returns:
- the same destination, written as YAML, for messages a person will read as well as a program
- Throws:
AceMqException- unless org.acemq:acemq-amqp-codec-yaml is on the classpath
-
asText
- Returns:
- the same destination, written as UTF-8 text; for payloads that are already strings
-
asBytes
- Returns:
- the same destination, written as raw bytes, for payloads something else has already encoded
-
codec
- Returns:
- the format this publisher writes
-
sendAsync
Description copied from interface:PublisherPublishes without waiting for the broker to confirm.A synchronous publish costs a round trip per message, so a loop over ten thousand of them spends nearly all its time waiting. This lets the next message go out while the last is still in flight, and is typically an order of magnitude faster for bulk work.
Nothing about the guarantees changes: the future carries the same result
Publisher.send(Object)returns, and fails the same way — including when nothing was bound to receive the message. What changes is when you find out.A future nobody waits on is a message nobody knows the fate of. That is the failure this library exists to prevent, so somebody has to check, eventually. If you do not intend to look at the result, use
Publisher.send(Object)and take the round trip.List<CompletableFuture<PublishResult>> inFlight = new ArrayList<>(); for (Order order : thousands) { inFlight.add(publisher.sendAsync(order)); } CompletableFuture.allOf(inFlight.toArray(new CompletableFuture[0])).join();Publishing blocks once too many messages are awaiting confirmation, which is deliberate: an asynchronous publisher with no ceiling is a memory leak that looks like throughput.
- Specified by:
sendAsyncin interfacePublisher<T>- Parameters:
payload- the payload to send- Returns:
- a future completed with the broker's answer, or failed as
Publisher.send(Object)would have thrown
-
sendAsync
Description copied from interface:PublisherPublishes without waiting, with an envelope of your own. -
sendAll
Description copied from interface:PublisherPublishes a batch and waits for every confirm.What most bulk publishing actually wants: the throughput of pipelining with the safety of having waited. Every message goes out before any confirm is awaited, then all of them are checked together.
Fails if any message failed, and the exception names how many succeeded — a partial batch is the normal outcome of a broker problem halfway through, and pretending otherwise would leave the caller resending messages that already arrived.
This is not atomic. AMQP has no such thing: there is no way to publish a hundred messages such that all or none arrive, and a library that offered one would be lying.
-
send
Description copied from interface:PublisherPublishes a message and waits for the broker to confirm it. -
send
Description copied from interface:PublisherPublishes a message built on an explicit envelope.Used when correlation or causation must be carried from a message being handled, so that a whole flow can be followed in traces and logs.
-
close
public void close()- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfacePublisher<T>
-
toString
-