Consider these two Exas trading messages via the
M register. Exa
XA reads from a file and sends them to the network register
NOTE XA - SENDER GRAB 199 MARK READING COPY F M TEST EOF FJMP READING
XB reads from
M and writes these messages to another file:
NOTE XB - RECEIVER MAKE MARK WRITING COPY M F TEST MRD TJMP WRITING
As you can see,
XA tests for the end of file (
XB tests for receivable messages (
MRD). This seems to be rather well designed, but most often ends up in
XB never finishing its job because there is nothing waiting in
TEST MRD is executed. Why is that?
Transfers via the
M register are not instantaneous. Before writing to
M it needs to be empty, before reading from
M the corresponding write operation has to be finished.
NOOP for timing
One solution for timing issues is to add additional
NOOP commands in your writing loop, telling your receiver to wait until the sender is back online.
NOTE XB - RECEIVER MAKE MARK WRITING COPY M F NOOP NOOP TEST MRD TJMP WRITING
If the job of
XA is to just read its file and die afterwards, your programme could be written even more compact:
NOTE XA - SENDER GRAB 199 MARK READING COPY F M JUMP READING NOTE CRASH AND BURN AT END OF FILE
XB having to wait one operation less than before:
NOTE XB - RECEIVER MAKE MARK WRITING COPY M F NOOP TEST MRD TJMP WRITING
By a rule of thumb the number of instructions in your receiver loop after your last read from
M and before doing
TEST MRD has to be as many instructions as it takes the sender to reach its next write to
M after its last write to
Sending “End Of Message”
If you do not want to think about timing, the receiving
XB can test for a marker which tells it that the end of the message has been reached.
This only works if you know for sure that the file you are reading from never contains the symbol
XA will use this as its “End Of Message” message (
NOTE XA - SENDER GRAB 199 MARK READING COPY F M TEST EOF FJMP READING NOTE EOF, SEND EOM COPY 0 M
XB now copies the message to
T, from where it is written into the file and is also executable from
FJMP. Remember: If
0, it is evaluated to
false – all other values will evaluate to
NOTE XB - RECEIVER MAKE MARK WRITING COPY M T COPY T F NOTE TEST EOM FROM `T` TJMP WRITING NOTE DELETE EOM FROM FILE SEEK -1 VOID F
Sending “Packet Size”
XA knows the file size it is reading to the network in advance, it is a very clever trick to send the file size to the receiver
XB as well. This way the
XB does not have to test for the message to end, but will know when all message chunks have been delivered.
XA will send the message size to
XB and use it for its own loop:
NOTE XA - SENDER GRAB 199 NOTE `T` CONTAINS THE NUMBER OF CHUNKS TO READ COPY T M MARK READING COPY F M NOTE COUNT DOWN REMAINING CHUNKS SUBI T 1 T TJMP READING
XB will have the same loop conditions:
NOTE XB - RECEIVER MAKE NOTE NOW `T` CONTAINS THE MESSAGE SIZE COPY M T MARK WRITING COPY M F NOTE COUNT DOWN REMAINING CHUNKS SUBI T 1 T TJMP WRITING
Sending “Keep Alive Messages”
For bullet-proof communication your best choice is to have
XA send a “keep alive message”…
NOTE XA - SENDER GRAB 199 MARK READING COPY F M TEST EOF NOTE SEND RESULT OF TEST TO M... COPY T M NOTE ...AND USE RESULT FOR YOUR OWN LOOP FJMP READING
NOTE XB - RECEIVER MAKE MARK WRITING COPY M F NOTE USE TEST RESULT TO TEST FOR YOURSELF TEST M = 1 FJMP WRITING
Every reading cycle
XB reads two messages from
M, where the second message contains
XA reached the end of its file. In this manner
XB continues to wait for messages as long as
XA explicitly tells it to by sending
1 in the second message.
This lets you skip all timing issues on the expends of more writes to the
M register. It adds just one extra line of Axiom code (but one less than having to
NOOP), but may end up producing more cycles.
If you are facing a multi-sender communication, things may get hairy. In this scenario, multiple senders transmit data to one receiver, which has to combine these messages into a single on.
Above solutions may apply, but if you are forced to deal with different message lengths which need to be combined, if may become very tricky to shut down the other sender as well, so your receiver stops its receiving cycle.
Imagine a scenario where first sender
XA knows when to quit, but second sender
XB does not; in this case, receiver
XB may go on receiving messages from
XB ad infinitum.
To solve this problem,
XA could literally use the
KILL command to shut down
XB. You may even opt to kill the receiver
XC as well whit this method.
Update 2018–09–06: Added section for “End Of Message” & “Packet Size”.
Update 2018–09–16: Added section for “Terminator”