Fence unmanaged lifecycle by snapshot time

Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-09-13 05:54:51 +00:00
committed by GitHub
co-authored by genichin
parent 84d81658a1
commit 8b1de8e26a
5 changed files with 239 additions and 34 deletions
@@ -21,6 +21,18 @@ class PostgreSQLUnmanagedPositionStore:
self._psycopg = _require_psycopg(psycopg_module)
self._dsn = dsn
@staticmethod
def _latest_snapshot_at(state: dict) -> datetime:
resolved_at = state.get("resolved_at")
last_seen_at = state.get("last_seen_at")
if isinstance(resolved_at, datetime) and (
not isinstance(last_seen_at, datetime) or resolved_at >= last_seen_at
):
return resolved_at
if isinstance(last_seen_at, datetime):
return last_seen_at
return state.get("updated_at") or state.get("created_at") or datetime.min.replace(tzinfo=UTC)
def observe(
self,
*,
@@ -43,6 +55,13 @@ class PostgreSQLUnmanagedPositionStore:
row = cur.fetchone()
previous = self._row_to_state(row) if row is not None else None
previous_quantity = previous.get("quantity") if previous is not None else None
if previous is not None and now < self._latest_snapshot_at(previous):
conn.rollback()
return {
"transition": "stale",
"previous_quantity": previous_quantity,
"state": previous,
}
if previous is None:
transition = "detected"
cur.execute(
@@ -54,6 +73,13 @@ class PostgreSQLUnmanagedPositionStore:
(instance_key, symbol, quantity, now, now, now, now, now),
)
elif previous["lifecycle_state"] == "resolved":
if now <= self._latest_snapshot_at(previous):
conn.rollback()
return {
"transition": "stale",
"previous_quantity": previous_quantity,
"state": previous,
}
transition = "detected"
cur.execute(
"UPDATE unmanaged_position_state "
@@ -63,29 +89,58 @@ class PostgreSQLUnmanagedPositionStore:
" operator_actor = NULL, operator_updated_at = NULL, "
" updated_at = %s "
"WHERE instance_key = %s AND symbol = %s "
" AND lifecycle_state = 'resolved' AND resolved_at < %s "
f"RETURNING {_STATE_COLUMNS}",
(quantity, now, now, now, instance_key, symbol),
(quantity, now, now, now, instance_key, symbol, now),
)
elif int(previous["quantity"]) != int(quantity):
if now <= previous["last_seen_at"]:
conn.rollback()
return {
"transition": "stale",
"previous_quantity": previous_quantity,
"state": previous,
}
transition = "quantity_changed"
cur.execute(
"UPDATE unmanaged_position_state "
"SET quantity = %s, last_seen_at = %s, quantity_changed_at = %s, "
" resolved_at = NULL, lifecycle_state = 'active', updated_at = %s "
"WHERE instance_key = %s AND symbol = %s "
" AND lifecycle_state = 'active' AND last_seen_at < %s "
f"RETURNING {_STATE_COLUMNS}",
(quantity, now, now, now, instance_key, symbol),
(quantity, now, now, now, instance_key, symbol, now),
)
else:
transition = "unchanged"
cur.execute(
"UPDATE unmanaged_position_state "
"SET last_seen_at = %s, updated_at = %s "
"WHERE instance_key = %s AND symbol = %s "
f"RETURNING {_STATE_COLUMNS}",
(now, now, instance_key, symbol),
)
state = self._row_to_state(cur.fetchone())
if now > previous["last_seen_at"]:
cur.execute(
"UPDATE unmanaged_position_state "
"SET last_seen_at = %s, updated_at = %s "
"WHERE instance_key = %s AND symbol = %s "
" AND lifecycle_state = 'active' AND quantity = %s AND last_seen_at < %s "
f"RETURNING {_STATE_COLUMNS}",
(now, now, instance_key, symbol, quantity, now),
)
fetched = cur.fetchone()
state = previous if fetched is None else self._row_to_state(fetched)
else:
conn.rollback()
return {
"transition": "unchanged",
"previous_quantity": previous_quantity,
"state": previous,
}
if transition != "unchanged":
fetched = cur.fetchone()
if fetched is None:
conn.rollback()
return {
"transition": "stale",
"previous_quantity": previous_quantity,
"state": previous,
}
state = self._row_to_state(fetched)
if transition != "unchanged":
note = (
f"previous_quantity={previous_quantity}"
@@ -139,14 +194,20 @@ class PostgreSQLUnmanagedPositionStore:
for state in active:
if state["symbol"] in observed_symbols:
continue
if now <= state["last_seen_at"]:
continue
cur.execute(
"UPDATE unmanaged_position_state "
"SET lifecycle_state = 'resolved', resolved_at = %s, updated_at = %s "
"WHERE instance_key = %s AND symbol = %s "
" AND lifecycle_state = 'active' AND last_seen_at < %s "
f"RETURNING {_STATE_COLUMNS}",
(now, now, instance_key, state["symbol"]),
(now, now, instance_key, state["symbol"], now),
)
resolved_state = self._row_to_state(cur.fetchone())
row = cur.fetchone()
if row is None:
continue
resolved_state = self._row_to_state(row)
resolved.append(resolved_state)
self._insert_audit(
cur,