Skip to content

Commit 7b8e31c

Browse files
added more asyncio freindly exception processing
1 parent 7fbc24d commit 7b8e31c

File tree

8 files changed

+1331
-1378
lines changed

8 files changed

+1331
-1378
lines changed

adbus/sdbus.c

Lines changed: 1293 additions & 1352 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

adbus/sdbus/method.pyx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ cdef void _method_message_handler(Method method, Message message):
1010
try:
1111
value = method.callback(*args)
1212
except Exception as e:
13-
method.exceptions.append(e)
13+
method.loop.call_exception_handler({'message': str(e), 'exception': e})
1414
error = Error()
1515
try:
1616
error.reply_from_exception(message, e)
1717
except SdbusError as e:
18-
method.exceptions.append(e)
18+
method.loop.call_exception_handler({'message': str(e), 'exception': e})
1919
return
2020

2121
message.new_method_return()
@@ -24,7 +24,7 @@ cdef void _method_message_handler(Method method, Message message):
2424
try:
2525
message.send()
2626
except SdbusError as e:
27-
method.exceptions.append(e)
27+
method.loop.call_exception_handler({'message': str(e), 'exception': e})
2828

2929
cdef int method_message_handler(sdbus_h.sd_bus_message *m,
3030
void *userdata, sdbus_h.sd_bus_error *err):
@@ -47,7 +47,6 @@ cdef class Method:
4747
cdef bytes name
4848
cdef bytes arg_signature
4949
cdef bytes return_signature
50-
cdef list exceptions
5150
cdef Object object
5251
cdef object loop
5352

@@ -58,7 +57,6 @@ cdef class Method:
5857
self.arg_signature = arg_signature.encode()
5958
self.return_signature = return_signature.encode()
6059
self.callback = callback
61-
self.exceptions = []
6260
self.object = None
6361

6462
self.type = sdbus_h._SD_BUS_VTABLE_METHOD

adbus/sdbus/object.pyx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@ cdef class Object:
88
cdef bytes path
99
cdef bytes interface
1010
cdef list vtable
11-
cdef list exceptions
1211
cdef object loop
1312

1413
def __cinit__(self, service, path, interface, vtable,
1514
depreciated=False, hidden=False):
1615
self.vtable = vtable
1716
self.path = path.encode()
1817
self.interface = interface.encode()
19-
self.exceptions = (<Service>service).exceptions
2018
self.bus = (<Service>service).bus
2119
self.loop = (<Service>service).loop
2220

@@ -63,14 +61,12 @@ cdef class Object:
6361
if type(v) == Method:
6462
(<Method>v).set_object(self)
6563
(<Method>v).populate_vtable(&self._vtable[i+1])
66-
(<Method>v).exceptions = self.exceptions
6764
self._vtable[i+1].x.method.offset = i*sizeof(self._userdata[0])
6865
self._userdata[i] = (<Method>v).userdata
6966

7067
elif type(v) == Property:
7168
(<Property>v).set_object(self)
7269
(<Property>v).populate_vtable(&self._vtable[i+1])
73-
(<Property>v).exceptions = self.exceptions
7470
self._vtable[i+1].x.method.offset = i*sizeof(self._userdata[0])
7571
self._userdata[i] = (<Property>v).userdata
7672

adbus/sdbus/property.pyx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@ cdef int property_get_handler(sdbus_h.sd_bus *bus,
1515
value = getattr(property.py_object, property.attr_name)
1616
message.append(property.signature, value)
1717
except Exception as e:
18+
property.loop.call_exception_handler({'message': str(e), 'exception': e})
1819
error = Error()
1920
try:
2021
error.reply_from_exception(message, e)
2122
except SdbusError as e:
2223
return -e.errno
2324
else:
2425
return 1
25-
finally:
26-
property.exceptions.append(e)
2726

2827
return 1
2928

@@ -42,15 +41,14 @@ cdef int property_set_handler(sdbus_h.sd_bus *bus,
4241
try:
4342
setattr(property.py_object, property.attr_name, values[0])
4443
except Exception as e:
44+
property.loop.call_exception_handler({'message': str(e), 'exception': e})
4545
error = Error()
4646
try:
4747
error.reply_from_exception(message, e)
4848
except SdbusError as e:
4949
return -e.errno
5050
else:
5151
return 1
52-
finally:
53-
property.exceptions.append(e)
5452

5553
return 1
5654

@@ -63,8 +61,8 @@ cdef class Property:
6361
cdef str attr_name
6462
cdef bytes name
6563
cdef bytes signature
66-
cdef list exceptions
6764
cdef Object object
65+
cdef object loop
6866

6967
def __cinit__(self, name, py_object, attr_name, signature='', read_only=False,
7068
depreciated=False, hidden=False, unprivileged=False,
@@ -74,7 +72,6 @@ cdef class Property:
7472
self.py_object = py_object
7573
self.attr_name = attr_name
7674
self.signature = signature.encode()
77-
self.exceptions = []
7875
self.object = None
7976

8077
if read_only:
@@ -120,6 +117,7 @@ cdef class Property:
120117
if self.object:
121118
raise SdbusError("Property already associated")
122119
self.object = object
120+
self.loop = (<Object>object).loop
123121

124122
def emit_changed(self):
125123
if not self.object:

adbus/sdbus/service.pyx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@ cdef class Service:
44
cdef sdbus_h.sd_bus *bus
55
cdef bytes name
66
cdef bool connected
7-
cdef list exceptions
87
cdef stdint.uint64_t flags
98
cdef object loop
109

1110
def __cinit__(self, name, loop=None, bus='system',
1211
replace_existing=False, allow_replacement=False, queue=False):
1312

1413
self.name = name.encode()
15-
self.exceptions = []
1614
self.flags = 0
1715
self.connected = False
1816
self.loop = loop
@@ -55,6 +53,10 @@ cdef class Service:
5553
"""Service is running."""
5654
return self.loop.is_running()
5755

56+
def get_loop(self):
57+
"""Get the service's asyncio loop."""
58+
return self.loop
59+
5860
def __dealloc__(self):
5961
self.bus = sdbus_h.sd_bus_unref(self.bus)
6062

@@ -77,11 +79,6 @@ cdef class Service:
7779
if r < 0:
7880
raise BusError(f"D-Bus Process Error: {errorcode[-r]}")
7981

80-
if self.exceptions:
81-
for callback_exception in self.exceptions[:]:
82-
self.exceptions.remove(callback_exception)
83-
raise callback_exception
84-
8582
if r == 0:
8683
break
8784
finally:

adbus/server/object.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ def emit_property_changed(self, py_name, dbus_name):
8585
self.sdbus.emit_properties_changed([dbus_name.encode()])
8686

8787
if self.changed_callback:
88-
self.changed_callback([py_name])
88+
self.service.get_loop().run_in_executor(
89+
None, self.changed_callback, [py_name]
90+
)
8991

9092
def defer_signals(self, enable):
9193
if enable:
@@ -101,7 +103,10 @@ def defer_signals(self, enable):
101103
)
102104

103105
if self.changed_callback:
104-
self.changed_callback(list(self._deferred_properties.values()))
106+
self.service.get_loop().run_in_executor(
107+
None, self.changed_callback,
108+
list(self._deferred_properties.values())
109+
)
105110

106111
self._deferred_properties = {}
107112

adbus/server/service.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,6 @@ def __init__(
5151

5252
def is_running(self):
5353
return self.sdbus.is_running()
54+
55+
def get_loop(self):
56+
return self.sdbus.get_loop()

tests/test_server.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ class TestObject(adbus.server.Object):
2525
signal1: int = adbus.server.Signal()
2626

2727
def __init__(self, service):
28-
super().__init__(service, object_path, object_interface)
28+
super().__init__(service, object_path, object_interface,
29+
changed_callback=self.dummy_cb)
2930

3031
@adbus.server.method()
3132
def test_method(self, r: int, gg: str) -> int:
@@ -37,9 +38,18 @@ def test_method2(self, r: int, gg: str) -> int:
3738

3839
@adbus.server.method()
3940
def slow_method(self) -> str:
40-
time.sleep(10)
41+
for _ in range(0, 5):
42+
time.sleep(1)
43+
print('-', end='', flush=True)
4144
return "Done"
4245

46+
@adbus.server.method()
47+
def slow_error(self) -> str:
48+
for _ in range(0, 5):
49+
time.sleep(1)
50+
print('-', end='', flush=True)
51+
raise RuntimeError("Slow Test")
52+
4353
@adbus.server.method()
4454
def error_method(self) -> str:
4555
raise RuntimeError("Test")
@@ -49,6 +59,11 @@ def var_method1(self, arg5: int, arg2: str, arg3, arg4, arg1: float):
4959
print(type(arg3))
5060
return str(arg3)
5161

62+
def dummy_cb(self, names):
63+
if len(names) > 1:
64+
print(f"{names} where updated")
65+
else:
66+
print(f"{names[0]} was updated")
5267

5368
class Test(unittest.TestCase):
5469
"""adbus method test cases."""

0 commit comments

Comments
 (0)