forked from SableClient/Sable
-
-
Notifications
You must be signed in to change notification settings - Fork 1
fix: search worker INIT timeout and runtime failure fallback #273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 7 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
46104aa
fix: fail fast when search worker startup stalls
Just-Insane 08aab2f
Clear search init timeout on worker error
Just-Insane f272f0c
Wait through IndexedDB blocked opens
Just-Insane 5e9ea63
Settle search worker failure state
Just-Insane f9f2934
Handle search worker ERROR teardown
Just-Insane 427e219
Merge branch 'integration' into codex/issue-256-search-worker
Just-Insane 0b84c6c
Tighten search worker failure cleanup
Just-Insane 93a5ea3
Merge branch 'integration' into codex/issue-256-search-worker
Just-Insane d680faf
Preserve search worker init errors
Just-Insane e921305
Ignore room additions after search worker failure
Just-Insane 80b3383
Clear stale search worker init errors on restart
Just-Insane File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| 'charm': patch | ||
| --- | ||
|
|
||
| fix: fail fast when search worker startup stalls |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| import { describe, expect, it, vi } from 'vitest'; | ||
| import { | ||
| buildSearchWorkerInitErrorMessage, | ||
| buildSearchWorkerRuntimeErrorMessage, | ||
| openSearchWorkerDb, | ||
| type IDBOpenRequestLike, | ||
| } from './workerLifecycle'; | ||
|
|
||
| function createOpenRequest() { | ||
| const listeners: Partial<Record<'success' | 'error', () => void>> = {}; | ||
| const close = vi.fn<() => void>(); | ||
| const request: IDBOpenRequestLike = { | ||
| result: { close } as unknown as IDBDatabase, | ||
| error: null, | ||
| onupgradeneeded: null, | ||
| onblocked: null, | ||
| addEventListener(type, listener) { | ||
| listeners[type] = () => listener(); | ||
| }, | ||
| }; | ||
|
|
||
| return { | ||
| request, | ||
| close, | ||
| fireSuccess: () => listeners.success?.(), | ||
| fireError: () => listeners.error?.(), | ||
| fireBlocked: () => | ||
| request.onblocked?.({ oldVersion: 0, newVersion: 1 } as IDBVersionChangeEvent), | ||
| }; | ||
| } | ||
|
|
||
| describe('buildSearchWorkerRuntimeErrorMessage', () => { | ||
| it('uses the worker error message when available', () => { | ||
| expect(buildSearchWorkerRuntimeErrorMessage({ message: 'boom' })).toBe( | ||
| 'Search worker runtime error: boom' | ||
| ); | ||
| }); | ||
|
|
||
| it('falls back to filename and coordinates for empty worker errors', () => { | ||
| expect( | ||
| buildSearchWorkerRuntimeErrorMessage({ | ||
| message: '', | ||
| filename: 'worker.js', | ||
| lineno: 12, | ||
| colno: 8, | ||
| }) | ||
| ).toBe('Search worker runtime error: Unknown worker error (worker.js:12:8)'); | ||
| }); | ||
| }); | ||
|
|
||
| describe('buildSearchWorkerInitErrorMessage', () => { | ||
| it('normalizes init failures into a stable message', () => { | ||
| expect(buildSearchWorkerInitErrorMessage(new Error('IndexedDB open blocked'))).toBe( | ||
| 'Search worker initialization failed: IndexedDB open blocked' | ||
| ); | ||
| }); | ||
| }); | ||
|
|
||
| describe('openSearchWorkerDb', () => { | ||
| it('resolves when indexedDB open succeeds', async () => { | ||
| const { request, fireSuccess } = createOpenRequest(); | ||
| const indexedDb = { open: vi.fn<() => IDBOpenRequestLike>(() => request) }; | ||
|
|
||
| const promise = openSearchWorkerDb(indexedDb, 'sable-search-test', 1000); | ||
| fireSuccess(); | ||
|
|
||
| await expect(promise).resolves.toBe(request.result); | ||
| }); | ||
|
|
||
| it('keeps waiting when indexedDB open is blocked and later succeeds', async () => { | ||
| const { request, fireBlocked, fireSuccess } = createOpenRequest(); | ||
| const indexedDb = { open: vi.fn<() => IDBOpenRequestLike>(() => request) }; | ||
|
|
||
| const promise = openSearchWorkerDb(indexedDb, 'sable-search-test', 1000); | ||
| fireBlocked(); | ||
| fireSuccess(); | ||
|
|
||
| await expect(promise).resolves.toBe(request.result); | ||
| }); | ||
|
|
||
| it('rejects when indexedDB open never settles', async () => { | ||
| vi.useFakeTimers(); | ||
| const { request, close, fireSuccess } = createOpenRequest(); | ||
| const indexedDb = { open: vi.fn<() => IDBOpenRequestLike>(() => request) }; | ||
|
|
||
| const promise = openSearchWorkerDb(indexedDb, 'sable-search-test', 50); | ||
| const rejection = promise.then( | ||
| () => { | ||
| throw new Error('Expected indexedDB open to time out'); | ||
| }, | ||
| (error) => error | ||
| ); | ||
| await vi.advanceTimersByTimeAsync(50); | ||
|
|
||
| await expect(rejection).resolves.toMatchObject({ | ||
| message: 'IndexedDB open timed out after 50ms for sable-search-test', | ||
| }); | ||
| fireSuccess(); | ||
| expect(close).toHaveBeenCalledOnce(); | ||
| vi.useRealTimers(); | ||
| }); | ||
| }); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.