This is important because rmr is *not* a persistent message bus, if any rmr client does not read "fast enough", messages can be lost.
So in this framework the client code is not in the same thread as the rmr reads, so that long running client code can never lead to lost messages.
-In the case of RMR Xapps, there are currently 3 total threads; the thread that reads from rmr directly, the thread that reads from the queue and invokes the client callback, and the user thread. Running the xapp returns to the user and runs until the user calls `stop`.
+In the case of RMR Xapps, there are currently 3 potential threads; the thread that reads from rmr directly, and the user can optionally have the rmr queue read run in a thread, returning execution back to the user thread.
+The default is only two threads however, where `.run` does not return back execution and the user code is "finished" at that point.
+
Examples
--------
:depth: 3
:local:
+[0.4.0] - 3/13/2020
+-------------------
+::
+
+ * minor breaking change; switches the default behavior RE threading for RMRXapps. The default is not to return execution, but the caller (in `run`) can choose to loop in a thread.
+
[0.3.0] - 3/10/2020
-------------------
Running the two examples (adjust for your shell notation)
+ pip install --user -e .
+ cd examples
set -x LD_LIBRARY_PATH /usr/local/lib/:/usr/local/lib64; set -x RMR_SEED_RT test_route.rt; python pong_xapp.py
-
+ (diff tmux window)
set -x LD_LIBRARY_PATH /usr/local/lib/:/usr/local/lib64; set -x RMR_SEED_RT test_route.rt; python ping_xapp.py
xapp = RMRXapp(default_handler=defh, post_init=post_init, use_fake_sdl=True)
xapp.register_callback(sixtyh, 60000)
-xapp.run()
+xapp.run() # will not thread by default
"""
self._dispatch[message_type] = handler
- def run(self):
+ def run(self, thread=False):
"""
This function should be called when the client xapp is ready to wait for their handlers to be called on received messages
- execution is returned to caller
+ Parameters
+ ----------
+ thread: bool (optional)
+ if thread is True, execution is returned to caller and the queue read loop is executed in a thread.
+ The thread can be stopped using .stop()
+ if False, execution is not returned and the framework loops
"""
def loop():
func = self._default_handler
func(self, summary, sbuf)
- Thread(target=loop).start()
+ if thread:
+ Thread(target=loop).start()
+ else:
+ loop()
def stop(self):
"""
setup(
name="ricxappframe",
- version="0.3.0",
+ version="0.4.0",
packages=find_packages(exclude=["tests.*", "tests"]),
author="Tommy Carpenter",
description="Xapp framework for python",
pass
rmr_xapp = RMRXapp(foo, post_init=post_init, rmr_wait_for_ready=False, use_fake_sdl=True)
- rmr_xapp.run()
+ # pytest will never return without thread and stop
+ rmr_xapp.run(thread=True)
time.sleep(1)
- rmr_xapp.stop() # pytest will never return without this.
+ rmr_xapp.stop()
self.rmr_free(sbuf)
rmr_xapp.register_callback(sixtythou_handler, 60000)
- rmr_xapp.run()
+ rmr_xapp.run(thread=True) # in unit tests we need to thread here or else execution is not returned!
time.sleep(1)