forked from M-Labs/artiq
protocols/broadcast,sync_struct: add disconnect callback
This commit is contained in:
parent
43aad0914e
commit
dcea48a52d
|
@ -9,11 +9,12 @@ _init_string = b"ARTIQ broadcast\n"
|
||||||
|
|
||||||
|
|
||||||
class Receiver:
|
class Receiver:
|
||||||
def __init__(self, name, notify_cb):
|
def __init__(self, name, notify_cb, disconnect_cb=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
if not isinstance(notify_cb, list):
|
if not isinstance(notify_cb, list):
|
||||||
notify_cb = [notify_cb]
|
notify_cb = [notify_cb]
|
||||||
self.notify_cbs = notify_cb
|
self.notify_cbs = notify_cb
|
||||||
|
self.disconnect_cb = disconnect_cb
|
||||||
|
|
||||||
async def connect(self, host, port):
|
async def connect(self, host, port):
|
||||||
self.reader, self.writer = \
|
self.reader, self.writer = \
|
||||||
|
@ -29,6 +30,7 @@ class Receiver:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
async def close(self):
|
async def close(self):
|
||||||
|
self.disconnect_cb = None
|
||||||
try:
|
try:
|
||||||
self.receive_task.cancel()
|
self.receive_task.cancel()
|
||||||
try:
|
try:
|
||||||
|
@ -41,15 +43,19 @@ class Receiver:
|
||||||
del self.writer
|
del self.writer
|
||||||
|
|
||||||
async def _receive_cr(self):
|
async def _receive_cr(self):
|
||||||
target = None
|
try:
|
||||||
while True:
|
target = None
|
||||||
line = await self.reader.readline()
|
while True:
|
||||||
if not line:
|
line = await self.reader.readline()
|
||||||
return
|
if not line:
|
||||||
obj = pyon.decode(line.decode())
|
return
|
||||||
|
obj = pyon.decode(line.decode())
|
||||||
|
|
||||||
for notify_cb in self.notify_cbs:
|
for notify_cb in self.notify_cbs:
|
||||||
notify_cb(obj)
|
notify_cb(obj)
|
||||||
|
finally:
|
||||||
|
if self.disconnect_cb is not None:
|
||||||
|
self.disconnect_cb()
|
||||||
|
|
||||||
|
|
||||||
class Broadcaster(AsyncioServer):
|
class Broadcaster(AsyncioServer):
|
||||||
|
|
|
@ -52,8 +52,10 @@ class Subscriber:
|
||||||
from the publisher. The mod is passed as parameter. The function is
|
from the publisher. The mod is passed as parameter. The function is
|
||||||
called after the mod has been processed.
|
called after the mod has been processed.
|
||||||
A list of functions may also be used, and they will be called in turn.
|
A list of functions may also be used, and they will be called in turn.
|
||||||
|
:param disconnect_cb: An optional function called when disconnection happens
|
||||||
|
from external causes (i.e. not when ``close`` is called).
|
||||||
"""
|
"""
|
||||||
def __init__(self, notifier_name, target_builder, notify_cb=None):
|
def __init__(self, notifier_name, target_builder, notify_cb=None, disconnect_cb=None):
|
||||||
self.notifier_name = notifier_name
|
self.notifier_name = notifier_name
|
||||||
self.target_builder = target_builder
|
self.target_builder = target_builder
|
||||||
if notify_cb is None:
|
if notify_cb is None:
|
||||||
|
@ -61,6 +63,7 @@ class Subscriber:
|
||||||
if not isinstance(notify_cb, list):
|
if not isinstance(notify_cb, list):
|
||||||
notify_cb = [notify_cb]
|
notify_cb = [notify_cb]
|
||||||
self.notify_cbs = notify_cb
|
self.notify_cbs = notify_cb
|
||||||
|
self.disconnect_cb = disconnect_cb
|
||||||
|
|
||||||
async def connect(self, host, port, before_receive_cb=None):
|
async def connect(self, host, port, before_receive_cb=None):
|
||||||
self.reader, self.writer = \
|
self.reader, self.writer = \
|
||||||
|
@ -78,6 +81,7 @@ class Subscriber:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
async def close(self):
|
async def close(self):
|
||||||
|
self.disconnect_cb = None
|
||||||
try:
|
try:
|
||||||
self.receive_task.cancel()
|
self.receive_task.cancel()
|
||||||
try:
|
try:
|
||||||
|
@ -90,20 +94,24 @@ class Subscriber:
|
||||||
del self.writer
|
del self.writer
|
||||||
|
|
||||||
async def _receive_cr(self):
|
async def _receive_cr(self):
|
||||||
target = None
|
try:
|
||||||
while True:
|
target = None
|
||||||
line = await self.reader.readline()
|
while True:
|
||||||
if not line:
|
line = await self.reader.readline()
|
||||||
return
|
if not line:
|
||||||
mod = pyon.decode(line.decode())
|
return
|
||||||
|
mod = pyon.decode(line.decode())
|
||||||
|
|
||||||
if mod["action"] == "init":
|
if mod["action"] == "init":
|
||||||
target = self.target_builder(mod["struct"])
|
target = self.target_builder(mod["struct"])
|
||||||
else:
|
else:
|
||||||
process_mod(target, mod)
|
process_mod(target, mod)
|
||||||
|
|
||||||
for notify_cb in self.notify_cbs:
|
for notify_cb in self.notify_cbs:
|
||||||
notify_cb(mod)
|
notify_cb(mod)
|
||||||
|
finally:
|
||||||
|
if self.disconnect_cb is not None:
|
||||||
|
self.disconnect_cb()
|
||||||
|
|
||||||
|
|
||||||
class Notifier:
|
class Notifier:
|
||||||
|
|
Loading…
Reference in New Issue