What is shelf?
shelf coordinates an ETS table for in-memory access and a DETS file for persistence. You work with a typed table handle in Gleam; shelf handles loading, validation, and snapshots through OTP's built-in storage APIs.
Open and validate
Section titled “Open and validate”When you call open(), shelf opens the DETS file and creates an ETS table.
If the file exists, shelf checks each saved key and value with your decoders
before loading them into ETS. If the file does not exist, you start with an
empty table. You must create the parent directory before opening the file.
The decoders let you detect stored data that does not match your application's types. If a new application version changes those types, you may need a schema migration before reopening the table.
Read and write
Section titled “Read and write”After loading, reads use ETS without DETS I/O. Writes follow the mode you choose when you open the table:
- WriteBack, the default: update ETS and call
save()to snapshot the changes to DETS. - WriteThrough: update DETS first, then ETS, on each write.
WriteThrough sends changes to DETS before returning, but DETS can buffer
them in memory. sync() flushes that buffer to the file. Neither mode
provides fsync(2)-level protection against OS crashes or power loss.
The write-mode guide explains the choice and links
to the full durability guarantees.
Keep the owner alive
Section titled “Keep the owner alive”The process that opens a table owns it. Other processes can read through the handle, but only the owner can write, save, reload, sync, or close. For a long-running application, open the table in a supervised actor or server and send mutation requests to that owner.
When the owner exits, ETS disappears and unsaved changes are lost. The next owner can reopen the DETS file and load its saved contents. See process ownership for the read/write split and crash behavior.
Save and close
Section titled “Save and close”save() copies the ETS contents to a temporary DETS file, then renames
that file over the database path. close() attempts a final save before
releasing the resources. With with_table, shelf also releases resources
if your callback returns an error or panics; a failed final save can still
lose unsaved changes.
Start with the quick start to open, save, and reopen your first table. Use persistence operations when you need to choose between saving, reloading, syncing, and closing.