How to change several fields at once¶
When you assign point.x and then point.y, that's two writes, and another
process can read the box in between and see a new x with an old
y. Reading two fields one after the other has the same
problem. This guide shows how to write and read several fields together, so
nobody sees a half-finished change.
1. Write them with update¶
update takes the fields by name and writes
them all in one go:
from sharedbox import SharedBox
class Point(SharedBox, name="example-point"):
x: int = 0
y: int = 0
point = Point()
point.update(x=3, y=4)
A reader in any process then sees either all of the new values or none of them.
2. Handle a value that is refused¶
update checks every value before it writes any of them, so if one is
wrong, nothing changes:
try:
point.update(x=5, y="six")
except TypeError as error:
print(error) # Point.y expects int, got str
print(point.x) # 3
3. Read them with snapshot¶
snapshot reads every field at the same
moment and gives you them in a dict:
4. Read the boxes a box refers to¶
A reference field shows up in a snapshot as a
BoxRef, which says which box it points at. Pass
follow=True to get the snapshot of that box instead:
class Probe(SharedBox, name="example-probe"):
depth: int = 0
point: Point | None = None
probe = Probe(2, point)
print(probe.snapshot()) # {'depth': 2, 'point': BoxRef(...)}
print(probe.snapshot(follow=True)) # {'depth': 2, 'point': {'x': 3, 'y': 4}}
Each box is read at its own moment, though, so the nested snapshot isn't taken at the same instant as the outer one.
The whole script
"""The script of the guide "How to change several fields at once"."""
from sharedbox import SharedBox
class Point(SharedBox, name="example-point"):
x: int = 0
y: int = 0
point = Point()
point.update(x=3, y=4)
try:
point.update(x=5, y="six")
except TypeError as error:
print(error) # Point.y expects int, got str
print(point.x) # 3
values = point.snapshot()
print(values) # {'x': 3, 'y': 4}
class Probe(SharedBox, name="example-probe"):
depth: int = 0
point: Point | None = None
probe = Probe(2, point)
print(probe.snapshot()) # {'depth': 2, 'point': BoxRef(...)}
print(probe.snapshot(follow=True)) # {'depth': 2, 'point': {'x': 3, 'y': 4}}
probe.close()
point.close()
Probe.unlink()
Point.unlink()