fix: use promise-based init to prevent race condition
- commit
- fe76e67de3c77cb34ae29281a47b03414f4e889c
- author
- bnema · · 2026-01-18 21:22 UTC
- parent
- 28802ca
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +19 -14
M src/hooks.server.ts +19 -14
| @@ -34,20 +34,25 @@ async function setAllUsersOffline() { | |||
| 34 | 34 | } | |
| 35 | 35 | ||
| 36 | 36 | // Initialize server (deferred, non-blocking for Cloudflare Workers compatibility) | |
| 37 | - | let initialized = false; | |
| 38 | - | async function initializeServer() { | |
| 39 | - | if (initialized) return; | |
| 40 | - | initialized = true; | |
| 41 | - | try { | |
| 42 | - | log.info('Initializing server...'); | |
| 43 | - | await ensureDefaultChatRoom(); | |
| 44 | - | await setAllUsersOffline(); | |
| 45 | - | log.info('Server initialized successfully'); | |
| 46 | - | } catch (error: unknown) { | |
| 47 | - | log.error('Failed to initialize server:', { error }); | |
| 48 | - | // Don't exit - let the server continue and retry on next request | |
| 49 | - | initialized = false; | |
| 50 | - | } | |
| 37 | + | let initPromise: Promise<void> | null = null; | |
| 38 | + | ||
| 39 | + | function initializeServer(): Promise<void> { | |
| 40 | + | if (initPromise) return initPromise; | |
| 41 | + | ||
| 42 | + | initPromise = (async () => { | |
| 43 | + | try { | |
| 44 | + | log.info('Initializing server...'); | |
| 45 | + | await ensureDefaultChatRoom(); | |
| 46 | + | await setAllUsersOffline(); | |
| 47 | + | log.info('Server initialized successfully'); | |
| 48 | + | } catch (error: unknown) { | |
| 49 | + | log.error('Failed to initialize server:', { error }); | |
| 50 | + | // Reset so next request can retry | |
| 51 | + | initPromise = null; | |
| 52 | + | } | |
| 53 | + | })(); | |
| 54 | + | ||
| 55 | + | return initPromise; | |
| 51 | 56 | } | |
| 52 | 57 | ||
| 53 | 58 | export const handle: Handle = async ({ event, resolve }) => { | |
| @@ -34,20 +34,25 @@ async function setAllUsersOffline() { | |||||
| 34 | } | 34 | } | ||
| 35 | 35 | ||||
| 36 | // Initialize server (deferred, non-blocking for Cloudflare Workers compatibility) | 36 | // Initialize server (deferred, non-blocking for Cloudflare Workers compatibility) | ||
| 37 | - | let initialized = false; | 37 | + | let initPromise: Promise<void> | null = null; |
| 38 | - | async function initializeServer() { | 38 | + | |
| 39 | - | if (initialized) return; | 39 | + | function initializeServer(): Promise<void> { |
| 40 | - | initialized = true; | 40 | + | if (initPromise) return initPromise; |
| 41 | - | try { | 41 | + | |
| 42 | - | log.info('Initializing server...'); | 42 | + | initPromise = (async () => { |
| 43 | - | await ensureDefaultChatRoom(); | 43 | + | try { |
| 44 | - | await setAllUsersOffline(); | 44 | + | log.info('Initializing server...'); |
| 45 | - | log.info('Server initialized successfully'); | 45 | + | await ensureDefaultChatRoom(); |
| 46 | - | } catch (error: unknown) { | 46 | + | await setAllUsersOffline(); |
| 47 | - | log.error('Failed to initialize server:', { error }); | 47 | + | log.info('Server initialized successfully'); |
| 48 | - | // Don't exit - let the server continue and retry on next request | 48 | + | } catch (error: unknown) { |
| 49 | - | initialized = false; | 49 | + | log.error('Failed to initialize server:', { error }); |
| 50 | - | } | 50 | + | // Reset so next request can retry |
| 51 | + | initPromise = null; | |||
| 52 | + | } | |||
| 53 | + | })(); | |||
| 54 | + | ||||
| 55 | + | return initPromise; | |||
| 51 | } | 56 | } | ||
| 52 | 57 | ||||
| 53 | export const handle: Handle = async ({ event, resolve }) => { | 58 | export const handle: Handle = async ({ event, resolve }) => { | ||