7. Choosing a transport: the QUIC broker
In chapter 6 you connected separately started juiz instances through the HTTP broker. In juiz, the part that talks to other juiz instances and outside programs is called a broker, and you choose brokers in the configuration file. In this chapter you connect the talker and the listener as in chapter 6, but through the QUIC broker instead of HTTP.
What is the QUIC broker?
Section titled “What is the QUIC broker?”QUIC is a transport that runs over UDP and carries several exchanges in parallel inside one encrypted connection.
The juiz QUIC broker sends data over QUIC encoded as MessagePack. Its broker type name is qmp (QUIC + MessagePack).
Compared with the HTTP broker:
| HTTP broker | QUIC broker | |
|---|---|---|
| Type name (start of the ID) | http |
qmp |
| Port | 8000 (TCP; 8001, 8002, … if in use) | Set in the configuration file (UDP; startup fails if in use) |
| Data format | JSON | MessagePack |
| Use from outside tools | Callable from Swagger UI or curl | Used between juiz instances |
Included in juiz |
Built in | Built in (0.0.18 and later) |
Prepare the configuration files
Section titled “Prepare the configuration files”The QUIC broker is built into the juiz command, so you only need to list it under brokers in the configuration file to instantiate it.
Create the following two files at the root of the example repository. They are the same for every language.
listener_qmp.conf, for the listener, makes the QUIC broker listen on UDP port 5000.
name: listener_qmpbrokers: - type_name: qmp name: qmp0 port: 5000talker_qmp.conf, for the talker, differs only in its name and port. Unlike the HTTP broker, the QUIC broker does not move to another port when its port is in use; juiz fails to start instead. Give each juiz its own port number.
name: talker_qmpbrokers: - type_name: qmp name: qmp0 port: 5001The name under brokers is required, but any name will do.
The commands you type in terminal 3 can also send requests to qmp:// IDs as they are. They need no configuration file.
Start the listener
Section titled “Start the listener”As in chapter 6, this chapter uses three terminals. Open each of them at the root of the example repository (for Python, activate the venv in every terminal).
In terminal 1, start the listener. It is the chapter 6 command with -f listener_qmp.conf added.
juiz -f listener_qmp.conf --process ./target/debug/liblistener.so -1 -djuiz -f listener_qmp.conf --process ./process/listener_python.py -l python -1 -djuiz -f listener_qmp.conf --process ./build/plugins/liblistener_cpp.so -l cpp -1 -dFrom terminal 3, pass an address starting with qmp:// to -s.
juiz -s qmp://127.0.0.1:5000 process list# => ["qmp://127.0.0.1:5000/process/listener0::listener"]juiz -s qmp://127.0.0.1:5000 process list# => ["qmp://127.0.0.1:5000/process/listener_python0::listener_python"]juiz -s qmp://127.0.0.1:5000 process list# => ["qmp://127.0.0.1:5000/process/listener_cpp0::listener_cpp"]The ID now starts with qmp://. This request went through the QUIC broker.
A juiz started with -d always starts the HTTP broker as well. So you can still query this juiz over HTTP on port 8000, as before.
juiz process list# => ["http://127.0.0.1:8000/process/listener0::listener"]juiz process list# => ["http://127.0.0.1:8000/process/listener_python0::listener_python"]juiz process list# => ["http://127.0.0.1:8000/process/listener_cpp0::listener_cpp"]The same listener has two IDs, one starting with http:// and one with qmp://. One juiz runs two brokers, and the start of the ID tells which one a request goes through.
Start the talker
Section titled “Start the talker”In terminal 2, start the talker. Again, it is the chapter 6 command with -f talker_qmp.conf added.
juiz -f talker_qmp.conf --process ./target/debug/libtalker.so -1 -r 1.0 -djuiz -f talker_qmp.conf --process ./process/talker_python.py -l python -1 -r 1.0 -djuiz -f talker_qmp.conf --process ./build/plugins/libtalker_cpp.so -l cpp -1 -r 1.0 -dTerminal 2 prints the talker’s output every second. From terminal 3, query port 5001 to check its ID.
juiz -s qmp://127.0.0.1:5001 process list# => ["qmp://127.0.0.1:5001/process/talker0::talker"]juiz -s qmp://127.0.0.1:5001 process list# => ["qmp://127.0.0.1:5001/process/talker_python0::talker_python"]juiz -s qmp://127.0.0.1:5001 process list# => ["qmp://127.0.0.1:5001/process/talker_cpp0::talker_cpp"]Connect over QUIC
Section titled “Connect over QUIC”In terminal 3, connect the talker’s output to the listener’s argument arg1. Just replace the IDs in the chapter 6 command with qmp:// IDs.
juiz connection create -t push \ "qmp://127.0.0.1:5001/process/talker0::talker" \ arg1 \ "qmp://127.0.0.1:5000/process/listener0::listener"juiz connection create -t push \ "qmp://127.0.0.1:5001/process/talker_python0::talker_python" \ arg1 \ "qmp://127.0.0.1:5000/process/listener_python0::listener_python"juiz connection create -t push \ "qmp://127.0.0.1:5001/process/talker_cpp0::talker_cpp" \ arg1 \ "qmp://127.0.0.1:5000/process/listener_cpp0::listener_cpp"The listener in terminal 1 starts printing. Ask the talker side, which holds the connection, and you can see that the destination is a qmp:// ID.
juiz -s qmp://127.0.0.1:5001 connection list# => [ConnectionID(src=ProcessIdentifier(core://core/process/talker0::talker, arg=arg1, dst=ProcessIdentifier(qmp://127.0.0.1:5000/process/listener0::listener)]juiz -s qmp://127.0.0.1:5001 connection list# => [ConnectionID(src=ProcessIdentifier(core://core/process/talker_python0::talker_python, arg=arg1, dst=ProcessIdentifier(qmp://127.0.0.1:5000/process/listener_python0::listener_python)]juiz -s qmp://127.0.0.1:5001 connection list# => [ConnectionID(src=ProcessIdentifier(core://core/process/talker_cpp0::talker_cpp, arg=arg1, dst=ProcessIdentifier(qmp://127.0.0.1:5000/process/listener_cpp0::listener_cpp)]The talker’s juiz sees that the destination ID starts with qmp:// and delivers the values to the listener over QUIC.
Call over QUIC
Section titled “Call over QUIC”Calls work the same way. With a qmp:// ID, the call goes through the QUIC broker.
juiz process call "qmp://127.0.0.1:5001/process/talker0::talker" '{}' -p# => CapsulePtr((value:Value("Hello World"), option: []))juiz process call "qmp://127.0.0.1:5001/process/talker_python0::talker_python" '{}' -p# => CapsulePtr((value:Value("Hello, World!"), option: []))juiz process call "qmp://127.0.0.1:5001/process/talker_cpp0::talker_cpp" '{}' -p# => CapsulePtr((value:Value("Hello, Juiz!"), option: []))Try it yourself
Section titled “Try it yourself”- Add the same
brokersas intalker_qmp.conftotalker_ec.conffrom chapter 6 and start it. Find the EC’s ID withjuiz -s qmp://127.0.0.1:5001 ec list, and start it withjuiz -s qmp://127.0.0.1:5001 ec start <ID>. - Connect again with only the destination changed to the
http://127.0.0.1:8000/...ID. The listener’s juiz runs both brokers, so the values arrive through either ID. - Send
juiz -s qmp://127.0.0.1:5002 process listto a port nobody listens on. QUIC runs over UDP, so the failure is not noticed right away; after a while you get the errorconnecting to qmp broker '127.0.0.1:5002' (127.0.0.1:5002) timed out.
Summary
Section titled “Summary”- The communication part of juiz is a broker. Besides the HTTP broker, you can choose the QUIC broker (
qmp). Both are built into thejuizcommand and instantiated underbrokersin the configuration file. - The start of an ID (
http://orqmp://) tells which broker a request goes through.juiz connection createandjuiz process calluse QUIC just by changing the ID. - One juiz can run several brokers at the same time. The same Process has one ID per broker.
- A Process’s code does not know which broker calls it. That is why the Process works unchanged when you change the transport.
This is the end of the tutorial. When you know what you want to do, look it up in the Guides.