Normalize recoverable rejection acknowledgements
This commit is contained in:
parent
59673a0739
commit
457abc0a51
3 changed files with 22 additions and 5 deletions
|
|
@ -23,14 +23,18 @@ class SyncErrorClassificationTest(unittest.TestCase):
|
|||
"generation_id TEXT,producer_peer_id TEXT,consumer_peer_id TEXT,"
|
||||
"consumed_at TEXT,result TEXT,ack_json TEXT)"
|
||||
)
|
||||
for generation, result in (("gen_consumed", "consumed"),
|
||||
("gen_rejected", "rejected"),
|
||||
("gen_other", "consumed")):
|
||||
for generation, result, diagnostic in (
|
||||
("gen_consumed", "consumed", ""),
|
||||
("gen_rejected", "rejected", "bounded rejection"),
|
||||
("gen_legacy", "rejected", "legacy/path"),
|
||||
("gen_other", "consumed", ""),
|
||||
):
|
||||
database.execute(
|
||||
"INSERT INTO sync_consumed_generations VALUES(?,?,?,?,?,?)",
|
||||
(generation, "android" if generation != "gen_other" else "other",
|
||||
"desktop", generation, result,
|
||||
json.dumps({"generation_id": generation, "result": result})),
|
||||
json.dumps({"generation_id": generation, "result": result,
|
||||
"diagnostic": diagnostic})),
|
||||
)
|
||||
|
||||
acknowledgements = sync_peer_worker.recovery_acknowledgements(
|
||||
|
|
|
|||
|
|
@ -566,6 +566,11 @@ def record_consumed(db: sqlite3.Connection, manifest: dict, manifest_digest: str
|
|||
|
||||
|
||||
def record_rejected(database: Path, manifest: dict, manifest_digest: str, diagnostic: str) -> dict:
|
||||
# Android's platform JSON quoter escapes solidus characters while the
|
||||
# desktop canonical encoder does not. Rejection diagnostics are bounded
|
||||
# presentation text, so normalize that separator before hashing the ACK;
|
||||
# identities and protocol fields remain untouched.
|
||||
diagnostic = diagnostic.replace("/", ":")
|
||||
diagnostic = diagnostic.encode("utf-8")[:MAX_DIAGNOSTIC].decode("utf-8", "ignore")
|
||||
with closing(connect_database(database)) as db:
|
||||
require_schema(db); db.execute("BEGIN IMMEDIATE")
|
||||
|
|
|
|||
|
|
@ -75,7 +75,15 @@ def recovery_acknowledgements(db, producer_peer_id: str, consumer_peer_id: str)
|
|||
"ORDER BY consumed_at,generation_id LIMIT 32",
|
||||
(producer_peer_id, consumer_peer_id),
|
||||
).fetchall()
|
||||
return [json.loads(row[0]) for row in rows]
|
||||
acknowledgements = [json.loads(row[0]) for row in rows]
|
||||
# ACKs created before rejection diagnostics were normalized may contain a
|
||||
# solidus that Android's platform JSON canonicalizer hashes differently.
|
||||
# They remain durable evidence but cannot close a peer row, so do not let
|
||||
# one legacy object block recovery of later compatible conversations.
|
||||
return [
|
||||
value for value in acknowledgements
|
||||
if value.get("result") != "rejected" or "/" not in value.get("diagnostic", "")
|
||||
]
|
||||
|
||||
|
||||
def run_adapter(
|
||||
|
|
|
|||
Loading…
Reference in a new issue