Blog ·

Solid Objects 1.0

Version 1.0 sets the public API promise for the Ruby on Rails gem and the Node.js package.

I released Solid Objects 1.0.0 for Ruby on Rails and Node.js under the MIT license. Solid Objects is a SQL-backed virtual actor library with stable actor identities, durable state, ordered operations, and automatic activation. State lives in the SQLite, PostgreSQL, or MySQL database that the application already uses.

What version 1.0 promises, and what it does not

The public API follows Semantic Versioning from 1.0.0. A patch release corrects defects. A minor release adds behavior without a public API break. Only a major release can break code that uses the public API.

The README and docs/ files in each repository define the public API. The new docs/versioning.md files state the promise and its limits for Rails and Node.js.

The promise excludes undocumented classes and exports, database schema, error message text, and log text. Error classes remain within the promise. A minor release can add tables, columns, and indexes, and supplies the migration. The npm package's Cloudflare Durable Objects backend, solid-objects/cloudflare, stays experimental and outside the promise.

A minor release can raise the minimum version of a language runtime or a database. It does this only for a version that its own project no longer supports. A patch release does not raise a minimum version.

Version 1.0 is a promise about the API. It is not a claim of measured scale.

One first-party application with more than 100,000 users runs it in production. That is a count of users, not a measure of load. I know of no production use by other people.

The project has one maintainer. The benchmarks in the repositories are development measurements and do not guarantee capacity. Longer soak tests remain open work.

Both runtimes now have the same core capabilities. The JavaScript repository records each capability, and each difference, in docs/parity.md. Tests run against SQLite, PostgreSQL, and MySQL.

The last breaking change

schedule returns an object. A reminder exists only after code calls an operation on that object.

Before 1.0, a turn that called no operation on that object stored no reminder and gave no error. The intended hold or timeout did not exist. My own blog included this mistake in a code sample. I corrected that sample.

The wrong call stops after the arguments: schedule(at: time, key: buyer) in Ruby, and this.schedule({ at: holdEnd, key: buyer }) in TypeScript. The correct call names an operation on the result.

Ruby
schedule(at: 10.minutes.from_now, key: buyer).expire(buyer:)
TypeScript
this.schedule({ at: holdEnd, key: buyer }).expire({ buyer })

From 1.0, that mistake raises ScheduleWithoutOperation, or SolidObjects::ScheduleWithoutOperation in Ruby. The runtime does not retry the turn. The message becomes a dead letter. The turn commits no state and no reminder.

A turn can keep the object and call an operation later in the same turn. Correct code does not change.

An observable cannot call schedule, with or without an operation. The turn that reads the observable fails with QueryMutatedState.

The 0.x releases changed the API between minor versions. A version below 1.0 tells readers to expect that. This mistake was the last case where wrong code failed with no error. With this correction, I am ready to stop API breaks.

How to upgrade

  1. Before the upgrade, find each schedule call in actors. Confirm that an operation follows each call in the same turn.
  2. For Rails, run bundle update solid_objects, then bin/rails solid_objects:doctor.
  3. For Node.js, run npm install solid-objects@latest.

The doctor has a new json check. At boot, the gem also warns if Active Support cannot decode JSON with the installed json gem. This affects json 3.x on Rails older than 8.1.4. Add gem "json", "~> 2" to the Gemfile, or use a newer Rails release.

Version 1.0.0 changes no schema or configuration.

What comes next

I will run longer soak tests and benchmarks with documented PostgreSQL and MySQL configuration. The commercial packages solid_objects_pro and @solidobjects/pro will follow the open-source packages at 1.0.0.

← All posts · RSS