Class PublisherSpec

java.lang.Object
org.acemq.workloads.PublisherSpec

public final class PublisherSpec extends Object
How the load is offered.

 .publishers(p -> p
         .threads(4)
         .rate(50_000)
         .payload(Payload.ofBytes(1024))
         .confirms(true))
 

Threads and rate are separate on purpose

"Ten producers" is not a load. Ten threads publishing as fast as they can is a different experiment from ten threads publishing five thousand messages a second each, and only the second one has a number you can hold the broker to.

rate(long) is the offered rate for the whole workload, divided across threads(int). The threads are a property of the client — how much parallelism the generator uses to keep up — and the rate is the property of the experiment.

  • Method Details

    • threads

      public PublisherSpec threads(int threads)
      Parameters:
      threads - how many threads share the offered rate. More threads help only when one cannot keep up with the schedule; the report says when that happened
      Returns:
      this spec
    • rate

      public PublisherSpec rate(long messagesPerSecond)
      The offered rate, in messages per second, across all publisher threads.

      This is a schedule, not a limit. Message n is due at start + n/rate, and if the broker cannot keep up the messages fall behind schedule rather than being quietly not sent. That lag is measured and reported, and it is the difference between "the broker did 180,000 a second" and "the broker was asked for 300,000 and fell four seconds behind".

      Parameters:
      messagesPerSecond - the offered rate
      Returns:
      this spec
    • unthrottled

      public PublisherSpec unthrottled()
      Publishes as fast as the client can, with no schedule.

      This measures throughput and invalidates latency. With no schedule there is no "due" time, so end-to-end latency is measured from the actual send — and a broker that stalls also stalls the generator, which stops offering load, which makes the recorded latency look better the worse the stall was. That is coordinated omission.

      Use it to find the ceiling. Then set rate(long) below the ceiling and measure latency there, which is the number that means something.

      Returns:
      this spec
    • payload

      public PublisherSpec payload(Payload payload)
      Parameters:
      payload - the message body
      Returns:
      this spec
    • messageSize

      public PublisherSpec messageSize(int size)
      Parameters:
      size - shorthand for payload(Payload.ofBytes(size))
      Returns:
      this spec
    • confirms

      public PublisherSpec confirms(boolean confirms)
      Publisher confirms.

      On by default, and turning them off changes what the throughput number means. Without confirms a publish is "handed to the socket" rather than "accepted by the broker": the rate goes up, and some of those messages were never durably anywhere. A number produced without confirms is not a number to promise a customer.

      Parameters:
      confirms - whether to wait for the broker to confirm
      Returns:
      this spec
    • maxMessages

      public PublisherSpec maxMessages(long max)
      Parameters:
      max - stop after this many messages, whichever comes first with the run duration
      Returns:
      this spec
    • maxInFlight

      public PublisherSpec maxInFlight(int inFlight)
      How many publishes a thread may have outstanding before it waits.

      This number is the difference between a generator that can offer a serious rate and one that cannot. A publish that waits for its own confirm costs a network round trip, so a thread doing that is capped at one message per round trip — about 550 a second against a broker 1.8ms away, whatever the broker is capable of. Reaching 300,000 that way would need five hundred threads.

      Publishing asynchronously with a window of outstanding confirms decouples the offered rate from the round trip. The window still bounds it: when the broker stops confirming, the window fills, sends are delayed, and that delay is reported as send lag rather than quietly disappearing.

      Parameters:
      inFlight - how many unconfirmed publishes each thread may hold
      Returns:
      this spec
    • maxInFlight

      public int maxInFlight()
    • threadCount

      public int threadCount()
    • rate

      public long rate()
      Returns:
      the offered rate, or 0 when unthrottled
    • isUnthrottled

      public boolean isUnthrottled()
    • payload

      public Payload payload()
    • confirms

      public boolean confirms()
    • maxMessages

      public long maxMessages()
    • toString

      public String toString()
      Overrides:
      toString in class Object