mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-21 00:02:30 +00:00
fix: ignore a reload the editor has moved on from, and settle saves before resolving
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
cb14f51445
commit
20e4424925
@@ -303,10 +303,17 @@
|
||||
labels: r.labels ?? undefined,
|
||||
wsSpecific: r.ws_specific ?? false
|
||||
}
|
||||
// Dropped after the read and before the baseline below: anything an autosave queued
|
||||
// while it was out belongs to the version being replaced, and leaving it parked would
|
||||
// let the fresh baseline make it acceptable — sending it over the version just chosen.
|
||||
UserDraftDbSyncer.dropPending(query)
|
||||
// Everything below writes shared editor state, so first make sure it is still this
|
||||
// resource's: the drawer stays closable while the read is out, and another resource
|
||||
// opened meanwhile would otherwise get this one's baseline — and with it this one's
|
||||
// path as its save target.
|
||||
if (selected !== ws || initialPath !== p) return
|
||||
// Anything an autosave queued while the read was out belongs to the version being
|
||||
// replaced. Dropping is not enough on its own: a POST the runner already started
|
||||
// cannot be cancelled, and if it settles after the baseline below, its rejection
|
||||
// raises the conflict again. So wait for the chain to go quiet first.
|
||||
await UserDraftDbSyncer.quiesce(query)
|
||||
if (selected !== ws || initialPath !== p) return
|
||||
UserDraftDbSyncer.clearConflict(query)
|
||||
initialStates[ws] = structuredClone(deployedState)
|
||||
UserDraftDbSyncer.recordRemoteSync(query, (r as any).draft_saved_at)
|
||||
|
||||
@@ -174,10 +174,17 @@
|
||||
labels: v.labels ?? undefined,
|
||||
wsSpecific: v.ws_specific ?? false
|
||||
}
|
||||
// Dropped after the read and before the baseline below: anything an autosave queued
|
||||
// while it was out belongs to the version being replaced, and leaving it parked would
|
||||
// let the fresh baseline make it acceptable — sending it over the version just chosen.
|
||||
UserDraftDbSyncer.dropPending(query)
|
||||
// Everything below writes shared editor state, so first make sure it is still this
|
||||
// variable's: the drawer stays closable while the read is out, and another variable
|
||||
// opened meanwhile would otherwise get this one's baseline — and with it this one's
|
||||
// path as its save target.
|
||||
if (selected !== ws || editPath !== p) return
|
||||
// Anything an autosave queued while the read was out belongs to the version being
|
||||
// replaced. Dropping is not enough on its own: a POST the runner already started
|
||||
// cannot be cancelled, and if it settles after the baseline below, its rejection
|
||||
// raises the conflict again. So wait for the chain to go quiet first.
|
||||
await UserDraftDbSyncer.quiesce(query)
|
||||
if (selected !== ws || editPath !== p) return
|
||||
UserDraftDbSyncer.clearConflict(query)
|
||||
initialStates[ws] = structuredClone(deployedState)
|
||||
UserDraftDbSyncer.recordRemoteSync(query, (v as any).draft_saved_at)
|
||||
|
||||
@@ -723,5 +723,20 @@ export const UserDraftDbSyncer = {
|
||||
const key = draftKey(query.workspace, query.itemKind, query.path)
|
||||
pendingSaveOpts.delete(key)
|
||||
debouncer.cancel(key)
|
||||
},
|
||||
|
||||
/**
|
||||
* Drop what is parked and wait until nothing for this key is still in flight. `dropPending`
|
||||
* alone cannot stop a POST the runner already started, and such a POST settles *after* the
|
||||
* caller has moved on — a rejected one re-raising the conflict it was told to resolve. Await
|
||||
* this before installing a baseline that would make a stale payload acceptable.
|
||||
*/
|
||||
async quiesce(query: UserDraftLastSyncQuery): Promise<void> {
|
||||
const key = draftKey(query.workspace, query.itemKind, query.path)
|
||||
this.dropPending(query)
|
||||
await runner.settled(key)
|
||||
// A save that landed while we waited parks its own opts again; they belong to the version
|
||||
// being replaced, so they go too.
|
||||
this.dropPending(query)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user