Skip to content

Commit 483d576

Browse files
fix(turso): initialize runtime sqlite pragmas for local db (#32)
1 parent af0c45d commit 483d576

2 files changed

Lines changed: 38 additions & 0 deletions

File tree

.changeset/quiet-apples-peel.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@workflow-worlds/turso": patch
3+
---
4+
5+
Configure runtime local SQLite connections with `PRAGMA journal_mode = WAL` and `PRAGMA busy_timeout = 5000` to reduce transient `SQLITE_BUSY` lock failures under e2e workloads.

packages/turso/src/index.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ export interface TursoWorldConfig {
9595

9696
// Module-level client cache to reuse connections
9797
const clientCache = new Map<string, Client>();
98+
const clientPragmaInit = new Map<string, Promise<void>>();
9899

99100
/**
100101
* Gets or creates a Turso client for the given URL.
@@ -111,6 +112,34 @@ function getOrCreateClient(url: string, authToken?: string): Client {
111112
return clientCache.get(cacheKey)!;
112113
}
113114

115+
/**
116+
* Configure SQLite pragmas for local file databases.
117+
* busy_timeout is per-connection, so this must run for runtime clients too.
118+
*/
119+
async function configureLocalSqlitePragmas(
120+
cacheKey: string,
121+
client: Client,
122+
databaseUrl: string
123+
): Promise<void> {
124+
if (!databaseUrl.startsWith('file:')) {
125+
return;
126+
}
127+
128+
const existing = clientPragmaInit.get(cacheKey);
129+
if (existing) {
130+
await existing;
131+
return;
132+
}
133+
134+
const init = (async () => {
135+
await client.execute('PRAGMA journal_mode = WAL');
136+
await client.execute('PRAGMA busy_timeout = 5000');
137+
})();
138+
139+
clientPragmaInit.set(cacheKey, init);
140+
await init;
141+
}
142+
114143
/**
115144
* Creates a Turso World instance.
116145
*
@@ -140,6 +169,8 @@ export function createWorld(config: TursoWorldConfig = {}): World {
140169
? parseInt(process.env.WORKFLOW_CONCURRENCY, 10)
141170
: 20);
142171

172+
const clientCacheKey = `${databaseUrl}:${authToken ?? ''}`;
173+
143174
// Get or create client
144175
const client = getOrCreateClient(databaseUrl, authToken);
145176

@@ -156,6 +187,8 @@ export function createWorld(config: TursoWorldConfig = {}): World {
156187
function ensureInitialized() {
157188
if (!initPromise) {
158189
initPromise = (async () => {
190+
await configureLocalSqlitePragmas(clientCacheKey, client, databaseUrl);
191+
159192
// Note: Schema must be created by running: pnpm exec workflow-turso-setup
160193
// Create components
161194
const storage = createStorage({ client });

0 commit comments

Comments
 (0)