fix: drain first-task completion during Today refresh (Closes #1156)
This commit is contained in:
parent
80863182d4
commit
16841f18e1
|
|
@ -303,7 +303,10 @@ function createTodaySync({ storage, getLogin, fetchJson, onRemoteIds, onRemotePl
|
||||||
let operations = pending();
|
let operations = pending();
|
||||||
let plan;
|
let plan;
|
||||||
let hadConflict = false;
|
let hadConflict = false;
|
||||||
if (!operations.length) plan = await fetchJson('api/v1/today');
|
if (!operations.length) {
|
||||||
|
plan = await fetchJson('api/v1/today');
|
||||||
|
operations = pending();
|
||||||
|
}
|
||||||
while (operations.length) {
|
while (operations.length) {
|
||||||
if (key() !== ownerKey) return false;
|
if (key() !== ownerKey) return false;
|
||||||
const batch = operations.slice(0, 50);
|
const batch = operations.slice(0, 50);
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,53 @@ sync.enqueue('add', 'issue:r:1:');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_activation_queued_during_an_empty_inflight_refresh_is_drained_before_it_settles():
|
||||||
|
script = f"""
|
||||||
|
const createTodaySync = require({json.dumps(str(TODAY_SYNC))});
|
||||||
|
const values = new Map();
|
||||||
|
const storage = {{get length(){{return values.size}},key:i=>[...values.keys()][i]||null,
|
||||||
|
getItem:k=>values.get(k)||null,setItem:(k,v)=>values.set(k,v),removeItem:k=>values.delete(k)}};
|
||||||
|
let releaseRefresh;
|
||||||
|
const refreshStarted = new Promise(resolve => {{ globalThis.refreshStarted = resolve; }});
|
||||||
|
const patches = [];
|
||||||
|
const statuses = [];
|
||||||
|
const sync = createTodaySync({{
|
||||||
|
storage, getLogin: () => 'timmy', createOperationId: () => 'activation-1',
|
||||||
|
fetchJson: async (_url, options={{}}) => {{
|
||||||
|
if (!options.method) {{
|
||||||
|
globalThis.refreshStarted();
|
||||||
|
await new Promise(resolve => {{ releaseRefresh = resolve; }});
|
||||||
|
return {{revision:0, ids:[]}};
|
||||||
|
}}
|
||||||
|
const operations = JSON.parse(options.body).operations;
|
||||||
|
patches.push(...operations);
|
||||||
|
return {{revision:1, ids:[], first_task_state:'complete',
|
||||||
|
accepted_operation_ids:operations.map(item => item.operation_id)}};
|
||||||
|
}},
|
||||||
|
onRemoteIds: () => {{}}, onStatus: state => statuses.push(state),
|
||||||
|
}});
|
||||||
|
(async () => {{
|
||||||
|
const refreshing = sync.flush();
|
||||||
|
await refreshStarted;
|
||||||
|
sync.enqueueActivation('complete');
|
||||||
|
const sharedFlush = sync.flush();
|
||||||
|
releaseRefresh();
|
||||||
|
await sharedFlush;
|
||||||
|
process.stdout.write(JSON.stringify({{
|
||||||
|
sharesInflight: refreshing === sharedFlush, patches, pending:sync.pending(), statuses,
|
||||||
|
}}));
|
||||||
|
}})();
|
||||||
|
"""
|
||||||
|
result = json.loads(subprocess.run(
|
||||||
|
["node", "-e", script], check=True, capture_output=True, text=True
|
||||||
|
).stdout)
|
||||||
|
|
||||||
|
assert result["sharesInflight"] is True
|
||||||
|
assert [operation["activation_state"] for operation in result["patches"]] == ["complete"]
|
||||||
|
assert result["pending"] == []
|
||||||
|
assert result["statuses"][-1] == "saved"
|
||||||
|
|
||||||
|
|
||||||
def test_operations_queued_in_the_same_millisecond_preserve_enqueue_order():
|
def test_operations_queued_in_the_same_millisecond_preserve_enqueue_order():
|
||||||
script = f"""
|
script = f"""
|
||||||
const createTodaySync = require({json.dumps(str(TODAY_SYNC))});
|
const createTodaySync = require({json.dumps(str(TODAY_SYNC))});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user