Skip to content

Commit 38ccbb0

Browse files
committed
Fix .cancel() not behaving as expected
1 parent a7588f6 commit 38ccbb0

File tree

3 files changed

+60
-101
lines changed

3 files changed

+60
-101
lines changed

frontend/src/lib/cancelable-promise-utils.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { CancelablePromise } from './gen'
22

33
export namespace CancelablePromiseUtils {
4-
export function then<T, U>(
4+
export function bind<T, U>(
55
promise: CancelablePromise<T>,
66
f: (value: T) => CancelablePromise<U>
77
): CancelablePromise<U> {
8-
return new CancelablePromise<U>((resolve, reject, onCancel) => {
9-
let promiseToBeCanceled: CancelablePromise<any> = promise
8+
let promiseToBeCanceled: CancelablePromise<any> = promise
9+
let p = new CancelablePromise<U>((resolve, reject, onCancel) => {
1010
onCancel(() => promiseToBeCanceled.cancel())
1111
promise
1212
.then((value1) => {
@@ -16,6 +16,8 @@ export namespace CancelablePromiseUtils {
1616
})
1717
.catch((err) => reject(err))
1818
})
19+
p.cancel = () => promiseToBeCanceled.cancel()
20+
return p
1921
}
2022

2123
export function pure<T>(value: T): CancelablePromise<T> {
@@ -30,24 +32,35 @@ export namespace CancelablePromiseUtils {
3032
promise: CancelablePromise<T>,
3133
f: (value: T) => U
3234
): CancelablePromise<U> {
33-
return then(promise, (value) => pure(f(value)))
35+
return bind(promise, (value) => pure(f(value)))
36+
}
37+
38+
export function pipe<T>(
39+
promise: CancelablePromise<T>,
40+
f: (value: T) => void
41+
): CancelablePromise<T> {
42+
promise.then(f)
43+
return promise
3444
}
3545

3646
export function catchErr<T, U>(
3747
promise: CancelablePromise<T>,
3848
f: (error: any) => CancelablePromise<U>
3949
): CancelablePromise<T | U> {
40-
return new CancelablePromise<T | U>((resolve, reject, onCancel) => {
41-
let promiseToBeCanceled: CancelablePromise<any> = promise
50+
let promiseToBeCanceled: CancelablePromise<any> = promise
51+
let p = new CancelablePromise<T | U>((resolve, reject, onCancel) => {
4252
onCancel(() => promiseToBeCanceled.cancel())
4353
promise
4454
.then((value) => resolve(value))
4555
.catch((err) => {
4656
let promise2 = f(err)
4757
promiseToBeCanceled = promise2
48-
promise2.then((value2) => resolve(value2)).catch((err2) => reject(err2))
58+
return promise2.then((value2) => resolve(value2)).catch((err2) => reject(err2))
4959
})
60+
.catch((err) => reject(err))
5061
})
62+
p.cancel = () => promiseToBeCanceled.cancel()
63+
return p
5164
}
5265

5366
export function finallyDo<T>(promise: CancelablePromise<T>, f: () => void): CancelablePromise<T> {

frontend/src/lib/components/auditLogs/AuditLogsFilters.svelte

Lines changed: 37 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
3333
import { userStore, workspaceStore } from '$lib/stores'
3434
import { ChevronDown, Loader2, RefreshCcw } from 'lucide-svelte'
35-
import { onDestroy, tick, untrack } from 'svelte'
35+
import { onDestroy, untrack } from 'svelte'
3636
import ToggleButtonGroup from '../common/toggleButton-v2/ToggleButtonGroup.svelte'
3737
import ToggleButton from '../common/toggleButton-v2/ToggleButton.svelte'
3838
import Select from '../select/Select.svelte'
@@ -43,7 +43,6 @@
4343
4444
let usernames: string[] | undefined = $state()
4545
let resources = usePromise(() => loadResources($workspaceStore!), { loadInit: false })
46-
let page: number | undefined = undefined
4746
4847
interface Props {
4948
logs?: AuditLog[]
@@ -90,73 +89,45 @@
9089
}
9190
})
9291
93-
function updatePerPage(newPerPage: number) {
94-
perPage = newPerPage
95-
}
96-
97-
function loadLogs(
98-
username: string | undefined,
99-
page: number | undefined,
100-
perPage: number | undefined,
101-
before: string | undefined,
102-
after: string | undefined,
103-
operation: string | undefined,
104-
resource: string | undefined,
105-
actionKind: ActionKind | undefined | 'all',
106-
scope: undefined | 'all_workspaces' | 'instance'
107-
) {
92+
function loadLogs() {
10893
loading = true
10994
110-
if (username == 'all') {
111-
username = undefined
112-
}
113-
if (operation == 'all' || operation == '') {
114-
operation = undefined
115-
}
116-
117-
// @ts-ignore
118-
if (actionKind == 'all' || actionKind == '') {
119-
actionKind = undefined
120-
}
121-
122-
if (resource == 'all' || resource == '') {
123-
resource = undefined
124-
}
95+
let username_ = username == 'all' ? undefined : username
96+
let operation_ = operation == 'all' || operation == '' ? undefined : operation
97+
let actionKind_ = actionKind == 'all' ? undefined : actionKind
98+
let resource_ = resource == 'all' || resource == '' ? undefined : resource
12599
126100
let _promise = AuditService.listAuditLogs({
127101
workspace: scope === 'instance' ? 'global' : $workspaceStore!,
128-
page,
102+
page: pageIndex,
129103
perPage,
130104
before,
131105
after,
132-
username,
133-
operation,
134-
resource,
135-
actionKind,
106+
username: username_,
107+
operation: operation_,
108+
resource: resource_,
109+
actionKind: actionKind_,
136110
allWorkspaces: scope === 'all_workspaces'
137111
})
138112
let promise = CancelablePromiseUtils.map(_promise, (value) => {
139113
logs = value
140114
hasMore = !logs || (logs.length > 0 && logs.length === perPage)
115+
loading = false
141116
})
142-
promise = CancelablePromiseUtils.onTimeout(promise, 1000, () => {
143-
sendUserToast('Loading audit logs is taking longer than expected...', true, [
144-
{
145-
label: 'Reduce to 25 items per page',
146-
callback: () => {
147-
_promise.cancel()
148-
updatePerPage(25)
149-
}
150-
}
151-
])
117+
console.log('loadLogs:')
118+
promise = CancelablePromiseUtils.onTimeout(promise, 4000, () => {
119+
sendUserToast(
120+
'Loading audit logs is taking longer than expected...',
121+
true,
122+
perPage > 25
123+
? [{ label: 'Reduce to 25 items per page', callback: () => (perPage = 25) }]
124+
: []
125+
)
152126
})
153127
promise = CancelablePromiseUtils.catchErr(promise, (e) => {
154128
if (e instanceof CancelError) return CancelablePromiseUtils.pure<void>(undefined)
155129
return CancelablePromiseUtils.pureErr<void>(e)
156130
})
157-
promise = CancelablePromiseUtils.finallyDo(promise, () => {
158-
loading = false
159-
})
160131
return promise
161132
}
162133
@@ -167,14 +138,7 @@
167138
: [$userStore?.username ?? '']
168139
}
169140
170-
let initialLoad = true
171-
function refreshLogs() {
172-
loadUsers()
173-
resources.refresh()
174-
return loadLogs(username, page, perPage, before, after, operation, resource, actionKind, scope)
175-
}
176-
177-
function updateLogs() {
141+
function updateQueryParams() {
178142
const queryParams: string[] = []
179143
180144
function addQueryParam(key: string, value: string | number | undefined | null) {
@@ -184,7 +148,7 @@
184148
}
185149
186150
addQueryParam('username', username)
187-
addQueryParam('page', page)
151+
addQueryParam('page', pageIndex)
188152
addQueryParam('perPage', perPage)
189153
addQueryParam('before', before)
190154
addQueryParam('after', after)
@@ -197,24 +161,6 @@
197161
}
198162
const query = '?' + queryParams.join('&')
199163
goto(query, { replaceState: true, keepFocus: true })
200-
201-
return loadLogs(username, page, perPage, before, after, operation, resource, actionKind, scope)
202-
}
203-
204-
function updateQueryParams() {
205-
if (initialLoad) return
206-
page = 1
207-
pageIndex = 1
208-
209-
return updateLogs()
210-
}
211-
212-
function updatePageQueryParams(pageIndex?: number | undefined) {
213-
if (initialLoad) {
214-
return
215-
}
216-
page = pageIndex
217-
updateLogs()
218164
}
219165
220166
window.addEventListener('popstate', handlePopState)
@@ -331,22 +277,22 @@
331277
WORKSPACES_DELETE: 'workspaces.delete'
332278
}
333279
334-
let refresh = $state(1)
335-
$effect(() => {
336-
;[$workspaceStore, refresh]
337-
let promise = untrack(() => refreshLogs())
338-
tick().then(() => (initialLoad = false))
339-
return () => promise.cancel()
340-
})
280+
let refresh = $state(0)
281+
let lastRefresh = $state(-1)
282+
341283
// observe all the variables that should trigger an update
342284
$effect(() => {
343-
;[username, perPage, before, after, operation, resource, actionKind, scope]
344-
let promise = updateQueryParams()
345-
return () => promise?.cancel()
346-
})
347-
// observe the pageIndex variable that should trigger an update
348-
$effect(() => {
349-
updatePageQueryParams(pageIndex)
285+
;[refresh, username, perPage, before, after, operation, resource, actionKind, scope, pageIndex]
286+
return untrack(() => {
287+
if (refresh !== lastRefresh) {
288+
loadUsers()
289+
resources.refresh()
290+
lastRefresh = refresh
291+
}
292+
updateQueryParams()
293+
let promise = loadLogs()
294+
return () => promise?.cancel()
295+
})
350296
})
351297
</script>
352298

frontend/src/lib/components/runs/JobsLoader.svelte

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
function onParamChanges() {
100100
resetJobs()
101101
let promise = loadJobsIntern(true)
102-
promise = CancelablePromiseUtils.onTimeout(promise, 1000, () => {
102+
promise = CancelablePromiseUtils.onTimeout(promise, 4000, () => {
103103
sendUserToast(
104104
'Loading jobs is taking longer than expected...',
105105
true,
@@ -240,7 +240,7 @@
240240
console.error(e)
241241
return CancelablePromiseUtils.pure([] as Job[])
242242
})
243-
promise = CancelablePromiseUtils.finallyDo(promise, () => {
243+
CancelablePromiseUtils.pipe(promise, () => {
244244
loadingFetch = false
245245
})
246246
return promise
@@ -289,7 +289,7 @@
289289
console.error(e)
290290
return CancelablePromiseUtils.pure({ jobs: [], obscured_jobs: [] } as ExtendedJobs)
291291
})
292-
promise = CancelablePromiseUtils.finallyDo(promise, () => {
292+
promise = CancelablePromiseUtils.pipe(promise, () => {
293293
loadingFetch = false
294294
})
295295
return promise

0 commit comments

Comments
 (0)