diff --git a/README.md b/README.md index 7d0b4f3..e5c4185 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,15 @@ an execution, and does not extend server result retention. It raises the same missing/cancelled execution errors described above. A second cursor cannot attach an execution already tracked by that connection. +On SQL sessions that support attachment, attaching a running execution +transfers event delivery to the new connection, even if the previous +connection remains open. The duplicate guard +only covers cursors on one connection. Another connection can attach again and +take event delivery back. The previous connection can also still cancel the +execution, including through cursor close or reuse. Callers must coordinate the +handoff so stale workers cannot reattach or cancel it; attach provides no +cross-connection lock or ownership fencing. + ### Stopping the SQL session Closing a connection leaves its SQL session running until diff --git a/wherobots/db/cursor.py b/wherobots/db/cursor.py index 93d80cf..f62bcaa 100644 --- a/wherobots/db/cursor.py +++ b/wherobots/db/cursor.py @@ -200,6 +200,8 @@ def attach(self, execution_id: str, store: Store | None = None) -> None: Connect to the original SQL session first. Pass the original Store for stored results. This never submits SQL or extends server result retention; a missing execution raises ExecutionNotFoundError when fetching. + On SQL sessions that support attachment, this transfers event ownership. + It does not fence other connections; callers must coordinate the handoff. """ if not isinstance(execution_id, str) or not execution_id.strip(): raise ProgrammingError("execution_id must be a non-empty string")