Skip to content

EBP-3104: Add best-practice Python request-reply reference samples - #9

Merged
aelsammak merged 1 commit into
devfrom
EBP-3104
Oct 1, 2026
Merged

aelsammak merged 1 commit into
devfrom
EBP-3104

Conversation

@aelsammak

@aelsammak aelsammak commented Sep 28, 2026 •

Copy link
Copy Markdown

What is the purpose of this change?

  • Add 4 new Python samples for request reply
  • Updated the naming scheme of samples to better fit the python public samples
    • blocking instead of using sync and no mention of async

How is this accomplished?

  1. Added python-direct-requestor-blocking-sample.py: one publish_await_response() with a positive 3000 ms reply timeout and a single retry on PubSubTimeoutError (JCSMP parity), then self-exit.
  2. Added python-direct-requestor-sample.py: five non-blocking publish() calls that each return a concurrent.futures.Future, so the requests are in flight together, then each Future is collected for its reply or its timeout.
  3. Added python-direct-replier-sample.py: RequestReplyMessageReceiver built with the request topic subscription, receive_async() with a RequestMessageHandler that guards on a None replier, echoes APPLICATION_MESSAGE_ID, and catches a failed reply().
  4. All three follow the EBP-3103 structure: shared connection-config helper, setup_solace / connect_solace / teardown with a populated state dataclass, service listeners before connect(), 3000 ms reconnect interval, SIGINT/SIGTERM shutdown, bounded terminate(). Exit code is 0 on success or a shutdown signal and 1 on a missing reply or a failure.
  5. Renamed the four EBP-3103 samples to drop -async (for example python-direct-publisher-sample.py), including the "Copied into a generated project as" docstring line.
  6. Corrected a stale comment in the guaranteed publisher that said the direct publisher pauses during a reconnect.

Anything reviews should focus on/be aware of?

  • The request-reply builders expose no back-pressure setting and their from_properties() applies no property, so these samples carry no buffer capacity constant, unlike the EBP-3103 samples. The comments say so.
  • publish_await_response() and Replier.reply() accept only an OutboundMessage, so these samples use the message builder where the direct publisher is builderless.
  • Only the blocking requestor retries once; the non-blocking requestor does not retry per Future. Is that the right split?
  • A shutdown signal during a blocking wait takes effect when the call returns, within the reply timeout.
  • Naming rule: -blocking means the call waits for the broker's answer (a reply or an ACK), not a back-pressure wait. A future publish_await_acknowledgement() sample would be python-guaranteed-publisher-blocking-sample.py.
  • Nothing routes to these files yet (SKILL.md, mode files, and evals are out of scope), so trigger and output evals were not run.

Verification (solace-pubsubplus 1.11.0, Python 3.13, local broker):

  • pyflakes clean on all Python samples
  • No-broker smoke test: 10/10 (imports, build before connect, teardown of an unconnected state, refused connect with clean teardown)
  • Live: replier + blocking requestor exit 0 with the correlated reply; replier + non-blocking requestor 5/5 replies, exit 0; replier SIGTERM exit 0
  • No replier: blocking requestor exits 1 after the retry (~6 s), non-blocking exits 1 (~4 s); SIGINT during the blocking wait exits 0

- Add python-direct-requestor-blocking-sample.py (publish_await_response with a positive reply timeout and one retry on PubSubTimeoutError), python-direct-requestor-sample.py (non-blocking publish() returning a Future per request, then collected), and python-direct-replier-sample.py (receive_async with a RequestMessageHandler, a None-replier guard, and reply())
- Direct only: the Python API has no guaranteed request-reply, so there is no counterpart to the JCSMP guaranteed requestor and replier
- Follow the EBP-3103 conventions: shared connection-config helper, listeners registered before connect(), 3000 ms reconnect interval, SIGINT/SIGTERM shutdown, bounded terminate(), exit code 1 on failure and 0 on a shutdown signal
- Document that the request-reply builders have no back-pressure setting and that their from_properties() applies no property
- Rename the four EBP-3103 samples to drop the -async suffix: a -blocking suffix now marks only a variant that waits for the broker's answer, matching the SolaceSamples naming
- Correct a stale guaranteed publisher comment that said the direct publisher pauses during a reconnect
- Verified against solace-pubsubplus 1.11.0: pyflakes clean, a no-broker smoke test, and live round trips from both requestors to the replier
@aelsammak
aelsammak marked this pull request as ready for review September 28, 2026 16:14

@mtite-sol mtite-sol left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes LGTM! Might be worth considering adding automated testing in the future to cover at least what you mentioned in your smoke tests. This can give us more confidence that samples still work when updating code / updating api version. Not needed for this PR though!

@aelsammak
aelsammak merged commit 3336321 into dev Oct 1, 2026
4 checks passed
@aelsammak
aelsammak deleted the EBP-3104 branch October 1, 2026 12:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants