@malloydata/db-duckdb 0.0.389 → 0.0.390

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -64,19 +64,24 @@ export declare class DuckDBConnection extends DuckDBCommon {
64
64
  close(): Promise<void>;
65
65
  idle(): Promise<void>;
66
66
  /**
67
- * Dispose this connection's stake in the underlying `DuckDBInstance`:
68
- * 1. Disconnect the per-connection C++ `Connection` so its
69
- * `ClientContext` stops pinning the `DatabaseInstance`.
70
- * 2. Drop our entry from the shared `activeDBs` bookkeeping.
71
- * 3. If we were the last sharer, close the instance — which releases
72
- * DuckDB's per-process file lock.
67
+ * Drop our entry from the shared `activeDBs` bookkeeping. If we were
68
+ * the last sharer, close the underlying `DuckDBInstance`.
73
69
  *
74
- * Step 1 is required even though step 3 calls `instance.closeSync()`.
75
- * The C-API `duckdb_close` only decrements the `shared_ptr<DatabaseInstance>`
76
- * refcount; live `Connection` objects keep that refcount above zero via
77
- * their `ClientContext`, so the file handle (and `fcntl` lock) survive
78
- * the `closeSync` call. Disconnecting first guarantees the `closeSync`
79
- * is the last ref and the lock is actually released.
70
+ * NOTE: this does NOT fully release the OS file lock when other
71
+ * processes try to open the same path. `duckdb_close` (= `closeSync`)
72
+ * is a refcount-decrement on `shared_ptr<DatabaseInstance>`; the
73
+ * `fcntl(F_SETLK)` lock on the storage manager's `UnixFileHandle`
74
+ * survives until the last `shared_ptr` ref is gone, and live C++
75
+ * `Connection` objects keep that refcount above zero via their
76
+ * `ClientContext`. To force the lock release we'd need to also
77
+ * `disconnectSync()` the per-connection node-api Connection — but
78
+ * doing so unconditionally (as 0.0.389 did) crashes the language
79
+ * server because malloy's translate/persistence layer retains
80
+ * weak_ptrs to the destroyed C++ Connection. See the commented-out
81
+ * code below and PR #2793 / the revert PR for context.
82
+ *
83
+ * Proper fix needs to coordinate disconnect with invalidation of
84
+ * whatever caches survive idle (manifest reader is the main suspect).
80
85
  */
81
86
  private detachInstance;
82
87
  /**
@@ -295,24 +295,36 @@ class DuckDBConnection extends duckdb_common_1.DuckDBCommon {
295
295
  // re-acquire the lock immediately and defeat the point of idling.
296
296
  }
297
297
  /**
298
- * Dispose this connection's stake in the underlying `DuckDBInstance`:
299
- * 1. Disconnect the per-connection C++ `Connection` so its
300
- * `ClientContext` stops pinning the `DatabaseInstance`.
301
- * 2. Drop our entry from the shared `activeDBs` bookkeeping.
302
- * 3. If we were the last sharer, close the instance — which releases
303
- * DuckDB's per-process file lock.
298
+ * Drop our entry from the shared `activeDBs` bookkeeping. If we were
299
+ * the last sharer, close the underlying `DuckDBInstance`.
304
300
  *
305
- * Step 1 is required even though step 3 calls `instance.closeSync()`.
306
- * The C-API `duckdb_close` only decrements the `shared_ptr<DatabaseInstance>`
307
- * refcount; live `Connection` objects keep that refcount above zero via
308
- * their `ClientContext`, so the file handle (and `fcntl` lock) survive
309
- * the `closeSync` call. Disconnecting first guarantees the `closeSync`
310
- * is the last ref and the lock is actually released.
301
+ * NOTE: this does NOT fully release the OS file lock when other
302
+ * processes try to open the same path. `duckdb_close` (= `closeSync`)
303
+ * is a refcount-decrement on `shared_ptr<DatabaseInstance>`; the
304
+ * `fcntl(F_SETLK)` lock on the storage manager's `UnixFileHandle`
305
+ * survives until the last `shared_ptr` ref is gone, and live C++
306
+ * `Connection` objects keep that refcount above zero via their
307
+ * `ClientContext`. To force the lock release we'd need to also
308
+ * `disconnectSync()` the per-connection node-api Connection — but
309
+ * doing so unconditionally (as 0.0.389 did) crashes the language
310
+ * server because malloy's translate/persistence layer retains
311
+ * weak_ptrs to the destroyed C++ Connection. See the commented-out
312
+ * code below and PR #2793 / the revert PR for context.
313
+ *
314
+ * Proper fix needs to coordinate disconnect with invalidation of
315
+ * whatever caches survive idle (manifest reader is the main suspect).
311
316
  */
312
317
  detachInstance() {
313
- if (this.connection) {
314
- this.connection.disconnectSync();
315
- }
318
+ // [PR #2793, reverted] Adding `this.connection?.disconnectSync()`
319
+ // here releases the OS file lock — but it also destroys C++ state
320
+ // that malloy-internal caches (manifest reader, etc.) hold
321
+ // weak_ptrs to. Result: SIGSEGV in the language server during
322
+ // translate, or `bad_weak_ptr` exceptions surfacing as model
323
+ // problems on next op. Left here as a marker for the proper fix.
324
+ //
325
+ // if (this.connection) {
326
+ // this.connection.disconnectSync();
327
+ // }
316
328
  const activeDB = DuckDBConnection.activeDBs[this.shareKey];
317
329
  if (activeDB) {
318
330
  activeDB.connections = activeDB.connections.filter(connection => connection !== this.connection);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/db-duckdb",
3
- "version": "0.0.389",
3
+ "version": "0.0.390",
4
4
  "license": "MIT",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -60,7 +60,7 @@
60
60
  "dependencies": {
61
61
  "@duckdb/duckdb-wasm": "1.33.1-dev13.0",
62
62
  "@duckdb/node-api": "1.4.4-r.1",
63
- "@malloydata/malloy": "0.0.389",
63
+ "@malloydata/malloy": "0.0.390",
64
64
  "@motherduck/wasm-client": "^0.6.6",
65
65
  "apache-arrow": "^17.0.0",
66
66
  "web-worker": "^1.3.0"