Skip to content

Plugins: a plugin's service gets zeron.db, the same file its windows open - #1380

Closed
hoangvu12 wants to merge 1 commit into
zeronsh:zeron/zgxfrom
hoangvu12:plugin-service-db
Closed

hoangvu12 wants to merge 1 commit into
zeronsh:zeron/zgxfrom
hoangvu12:plugin-service-db

Conversation

@hoangvu12

@hoangvu12 hoangvu12 commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

A plugin's service has no database. zeron.db exists only in its windows, so a service that keeps real data (a design tool's documents, an index, a history) has only zeron.store, which holds 1 MB in total. We hit this moving Zeron Design to a Luau plugin. Its service owns every Design and runs agents' calls with no window open, and every call failed with "attempt to index nil with 'exec'".

Now a service has zeron.db.exec and zeron.db.query, with the same calls and promises as a window's. They open the same file, <data>/plugins/.storage/<id>.sqlite3, so what the service writes the windows read.

  • The database code moved out of the app into crates/plugin-db. The app and the engine both use it, so the rules are written once: bound parameters only, no other file attached, and pragmas that lift the limits refused.
  • Two processes now hold the file. Each opens it in WAL mode with a 5 s busy timeout, so a write that meets the other side's write waits instead of failing. The 100 MB limit is the file's max_page_count, so it's counted once for both.
  • The engine runs each call with spawn_blocking, so a wait on the window's write doesn't stall the VM.

Testing

  • zeron-plugin-db: the app's three tests moved unchanged. A new test, two_processes_share_one_database, runs its own binary again as a second process. The two processes write 400 rows each at once, reading between writes, and then both fill the database. No write is lost, no call fails on the other's lock, integrity_check is ok, and the file stops at one limit.
  • zeron-engine: a_service_and_its_windows_share_one_database writes from a service, reads the row from the window's path, and the reverse. The rows outlive the service stopping, and an ATTACH is refused.
  • Tried end to end in a local build of the app and engine: the Design plugin stored its Designs from the service and its windows read them.

cargo test -p zeron-plugin-db passes. cargo test -p zeron-engine --lib a_service_and_its_windows_share_one_database passes. On Windows the engine's lib tests need the two libc::getrusage test helpers gated to unix (chat_persistence.rs, source_control.rs) to compile. They fail the same way without this change, and that gate isn't in this PR. cargo metadata --locked resolves both workspaces.

@hoangvu12

Copy link
Copy Markdown
Contributor Author

Folded into #1392, which combines our plugin pull requests into one for review. This change is its commit cc9d259.

@hoangvu12 hoangvu12 closed this Nov 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant