solid_objects 0.14.0 → 0.14.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +75 -0
- data/README.md +349 -1124
- data/Rakefile +5 -0
- data/docs/architecture.md +40 -1
- data/docs/correctness.md +9 -0
- data/docs/operations.md +169 -21
- data/docs/reminders.md +112 -0
- data/docs/roadmap.md +7 -1
- data/examples/at_least_once/actor.rb +14 -0
- data/examples/at_least_once/boot.rb +47 -0
- data/examples/at_least_once/demo.rb +92 -0
- data/examples/at_least_once/effect_worker.rb +40 -0
- data/examples/at_least_once/sink.rb +27 -0
- data/lib/solid_objects/actor_channel.rb +33 -3
- data/lib/solid_objects/engine.rb +4 -0
- data/lib/solid_objects/version.rb +1 -1
- data/sig/generated/lib/solid_objects/actor_channel.rbs +10 -0
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 68d50b21673b5b8339754b9a0003500ac57c253877f04b26d4677d2adc260c1d
|
|
4
|
+
data.tar.gz: 16dda2e055602604f8b8158558fba9a41790a32ec5235ee04ae450ee02217c14
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 774ce46b5448030d6b51d449e7ab18f9c2e68d42a1ce47496b8bc5223bb5588ac7350d1f2c47894dac1ea3d3b9c19b2d8b87c7eb7832aba28c3e5a71dcb436fd
|
|
7
|
+
data.tar.gz: 5ec7bcc03c1a9875962642b8fc80d912472c9f1a10e088685f276542959e86f6057670f20d9085e2e554f0a8a06763b7c75f1ad7937b7280ea532c862ec3f50d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,80 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.14.2 - 2026-08-25
|
|
4
|
+
|
|
5
|
+
- Rewrite the first screen around the objection a reader actually has. The
|
|
6
|
+
README led with a counter incrementing an integer, which invites the reply
|
|
7
|
+
that one line of SQL already does it. It now leads with the ticket sale from
|
|
8
|
+
the homepage: 100 seats, a hold, a ten-minute expiry that frees the seat, and
|
|
9
|
+
a live count. That is the smallest example needing three things from one
|
|
10
|
+
number, and the three things are the argument.
|
|
11
|
+
- Answer "why not just use transactions?" in the first screen rather than at
|
|
12
|
+
line 1245 of a 1370-line file. The section concedes `with_lock` first, then
|
|
13
|
+
argues scope rather than discipline: any `expires_at` or `scheduled_at`
|
|
14
|
+
column is evidence the critical section already outlived the lock, and what
|
|
15
|
+
follows it is a sweeper and a race. The comparisons table gains the row
|
|
16
|
+
people actually reach for.
|
|
17
|
+
- Add "Is it worth installing here?", which names who should not install this,
|
|
18
|
+
and point readers with high-QPS reads or hot identities at
|
|
19
|
+
[Solid Objects Pro](https://solidobjects.pro/).
|
|
20
|
+
- Fix the reactive example, which could not run. A scalar observable raises
|
|
21
|
+
unless it is declared `broadcast: :value`, and a component dependency must
|
|
22
|
+
itself be a declared observable. The example now declares both. The reactive
|
|
23
|
+
section also claimed a fragment is re-rendered once per change; the turn
|
|
24
|
+
records the broadcast atomically, while delivery retries and is at least
|
|
25
|
+
once.
|
|
26
|
+
- Cut the README from 1370 to about 580 lines by moving reference material into
|
|
27
|
+
`docs/`, and add `CONTRIBUTING.md`. Reminders now have their own guide at
|
|
28
|
+
`docs/reminders.md`, `docs/operations.md` gains the configuration defaults
|
|
29
|
+
table, the worker-count flags, the upgrade sequence and the extension
|
|
30
|
+
component contract, and `docs/architecture.md` gains `register_effect` and
|
|
31
|
+
`register_commit_action` with their signatures.
|
|
32
|
+
|
|
33
|
+
## 0.14.1 - 2026-08-24
|
|
34
|
+
|
|
35
|
+
- Register application actors in every process that boots the application.
|
|
36
|
+
The engine now loads the host application's `app/actors` directories from a
|
|
37
|
+
`to_prepare` hook, which previously only the `solid_objects start` process
|
|
38
|
+
did. An actor registers itself as a side effect of its class loading, so a
|
|
39
|
+
lazily loading web process began with an empty registry. `ActorChannel`
|
|
40
|
+
looks the actor up by name, and the resulting `UnknownActorType` reached the
|
|
41
|
+
rescue that rejects the subscription: a Cable subscription for a real actor
|
|
42
|
+
was rejected in any web process that had not yet rendered that actor, and
|
|
43
|
+
the page kept a card that never updated. `ComponentsController` resolves the
|
|
44
|
+
same way through `ActorSnapshot`. `Transmission.receive` already carried a
|
|
45
|
+
registry-miss retry for this reason, and it stays as a guard for a host that
|
|
46
|
+
reaches the gem without the engine.
|
|
47
|
+
- Report why a Cable subscription was rejected. Every reject path in
|
|
48
|
+
`ActorChannel#subscribed` now emits `solid_objects.subscription.rejected`
|
|
49
|
+
with a `reason`, the actor identity, and the `error_class` where an
|
|
50
|
+
exception caused it. Five conditions previously collapsed into one silent
|
|
51
|
+
`reject`, which is invisible from the browser and left nothing in the log to
|
|
52
|
+
distinguish an unregistered actor type from a tampered token. Exception
|
|
53
|
+
messages stay out of the payload, because a component or payload failure can
|
|
54
|
+
carry actor state.
|
|
55
|
+
|
|
56
|
+
- State where `async` waits when no worker runs. The `async` section of the
|
|
57
|
+
README and the runtime section of `docs/operations.md` now say that the
|
|
58
|
+
generator and the migrations start no role, so an application that serves
|
|
59
|
+
web requests alone leaves the message ready until
|
|
60
|
+
`bundle exec solid_objects start` runs the roles. The message is durable
|
|
61
|
+
and waits; it is not lost. `test/integration/background_pickup_test.rb`
|
|
62
|
+
pins it: the message reads `ready` and the actor state stays empty until a
|
|
63
|
+
worker runs. This matches solid-objects-js#22, which reported the same gap
|
|
64
|
+
for `runtime.run(signal)` in the Node package.
|
|
65
|
+
|
|
66
|
+
- Add `examples/at_least_once` and `bundle exec rake at_least_once`, an
|
|
67
|
+
executable proof that the at-least-once clause fires and that the
|
|
68
|
+
documented remedy absorbs it. One actor turn stages an effect that writes
|
|
69
|
+
to an external sink file. The first effect worker crashes between the sink
|
|
70
|
+
write and the acknowledgement, and a second worker reclaims the stale
|
|
71
|
+
effect after the liveness threshold and delivers again. With deduplication
|
|
72
|
+
off the sink reads 2, both deliveries carrying the same `context.id` at
|
|
73
|
+
attempts 1 and 2; with a guard on that id the sink reads 1. The actor state
|
|
74
|
+
commits exactly once in both runs. CI runs the demo in the SQLite job, and
|
|
75
|
+
`docs/correctness.md` links it from the handler idempotency section. This
|
|
76
|
+
mirrors `pnpm run test:at-least-once` in solid-objects-js.
|
|
77
|
+
|
|
3
78
|
## 0.14.0 - 2026-08-22
|
|
4
79
|
|
|
5
80
|
- Add `SolidObjects::Transmission.receive(envelope)`, the server ingest for
|