cable_room 0.6.2.beta3 → 0.7.0.beta1
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 +122 -0
- data/README.md +1190 -0
- data/cable_room.gemspec +5 -2
- data/exe/cable_room +8 -0
- data/lib/cable_room/broadcaster.rb +116 -0
- data/lib/cable_room/bus.rb +372 -0
- data/lib/cable_room/cli.rb +237 -0
- data/lib/cable_room/config.rb +112 -0
- data/lib/cable_room/host/bus_inbound.rb +36 -0
- data/lib/cable_room/host/runner.rb +571 -0
- data/lib/cable_room/host/supervisor.rb +275 -0
- data/lib/cable_room/host/worker_pool.rb +37 -0
- data/lib/cable_room/host.rb +477 -0
- data/lib/cable_room/membership_store.rb +105 -0
- data/lib/cable_room/migration.rb +586 -0
- data/lib/cable_room/periodic_timer.rb +18 -0
- data/lib/cable_room/placement.rb +258 -0
- data/lib/cable_room/ports.rb +19 -11
- data/lib/cable_room/railtie.rb +3 -12
- data/lib/cable_room/room/base.rb +45 -39
- data/lib/cable_room/room/host_adapter.rb +52 -0
- data/lib/cable_room/room/lifecycle.rb +26 -9
- data/lib/cable_room/room/port_management.rb +58 -4
- data/lib/cable_room/room/reaping.rb +34 -1
- data/lib/cable_room/room/snapshotting.rb +78 -0
- data/lib/cable_room/room/threading.rb +2 -2
- data/lib/cable_room/room/user_management.rb +27 -0
- data/lib/cable_room/room.rb +5 -2
- data/lib/cable_room/room_member.rb +258 -13
- data/lib/cable_room/room_proxy_channel.rb +13 -2
- data/lib/cable_room/snapshot.rb +136 -0
- data/lib/cable_room/version.rb +1 -1
- data/lib/cable_room.rb +57 -2
- metadata +25 -9
- data/lib/cable_room/channel_base.rb +0 -247
- data/lib/cable_room/channel_tracker.rb +0 -130
- data/lib/cable_room/room/channel_adapter.rb +0 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 890aa545d8211663c2270322da9440b0dbd685e7cdcfa9858df04390d06e7533
|
|
4
|
+
data.tar.gz: 074e6c49a9886c90483500bdb61cdf40fa4d3c9e83ddc583415cc9ac051e90f6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3304bd77c3d455a2b867d83d82d4985ff7e1a3ec10bd80ec6a097f50be040fadbbaac501d7f26234384ba50dbe9f09864c92e1114d8cecff75d308ae2a770261
|
|
7
|
+
data.tar.gz: 408c73ab717cd8aaa5a7fbc8ce6b5d209ee2169fe50a731ac8b6d7b2b417b61e64c5a9ceac55155e07e677f6b3a952bb56edd4043a16b624bb264cd6ca1fb21d
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Changelog.
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
Rooms can now run in their own process pool, and browsers can be served by anycable-go. Every
|
|
6
|
+
Room definition from 0.6 works unchanged. The channel and deployment contracts do change; the
|
|
7
|
+
README's "Upgrading from 0.6 to 1.0" section is the checklist.
|
|
8
|
+
|
|
9
|
+
### Breaking.
|
|
10
|
+
|
|
11
|
+
- **Clients must send `hello`.** A membership no longer announces itself to the Room when the
|
|
12
|
+
channel subscribes. The browser performs `hello` once ActionCable confirms the subscription
|
|
13
|
+
(`connected()` in the JS client), and only then does `port_connected` go out. There is no
|
|
14
|
+
fallback: a client that never says `hello` receives broadcasts on the shared stream, but the
|
|
15
|
+
Room never sees it and everything it sends is dropped. Browser tabs open across the deploy
|
|
16
|
+
speak the old handshake and stay deaf until reloaded.
|
|
17
|
+
- **`ChannelBase`, `ChannelTracker`, and `DummyConnection` are gone.** Rooms no longer run inside
|
|
18
|
+
a synthetic ActionCable channel. `CableRoom::Host` (one per process) and `Host::Runner` (one
|
|
19
|
+
per Room) own the work queue, worker pool, scheduler, Redlock renewal, watchdog, and shutdown.
|
|
20
|
+
Internal names apps may have reached for moved with them:
|
|
21
|
+
- inside a Room, `@cable_channel` is now `@runner` (a `Host::Runner`);
|
|
22
|
+
- the `CableRoom.error_handler` context key `channel:` is now `runner:` (with `room:`,
|
|
23
|
+
`room_class:`, and `room_key:` alongside it);
|
|
24
|
+
- `Room#params` is gone (it delegated to the synthetic channel, which had none);
|
|
25
|
+
- `ChannelTracker::BEAT_INTERVAL` is `Host::BEAT_INTERVAL`;
|
|
26
|
+
- `Room::ChannelAdapter` is `Room::HostAdapter`, and the `MyRoom::Channel` constant no longer
|
|
27
|
+
exists;
|
|
28
|
+
- `CableRoom::Room.locally_open_rooms` and `MyRoom.locally_running_instances` read from the
|
|
29
|
+
Host and return `[]` in a process that hosts no Rooms.
|
|
30
|
+
- **Provisioning happens over the bus.** `join_room(..., create: true)` never starts a Room in
|
|
31
|
+
the member's process. It publishes a `provision` request (at join and on every ping until the
|
|
32
|
+
Room acknowledges the port), and one of the hosts starts the Room after a load-weighted
|
|
33
|
+
delay. `Room::Base.ensure` still starts a Room directly, but only in a process that hosts
|
|
34
|
+
Rooms: in a `room_host = :remote` web process it raises `CableRoom::Host::NotHosting`.
|
|
35
|
+
- **Member→room traffic rides cable_room's own Redis.** Everything a member sends (`to_room`,
|
|
36
|
+
`port_connected`, `port_ping`, `port_disconnected`, custom ports) and `Room::Base.send_message`
|
|
37
|
+
publish on `CableRoom::Bus`, over the `CABLEROOM_*` connection. The Room side no longer
|
|
38
|
+
touches ActionCable pubsub for inbound. That connection must be reachable from every web
|
|
39
|
+
process and every rooms host.
|
|
40
|
+
- **`redis` is a runtime dependency** (`>= 5.0`). It was a development dependency; rediconn
|
|
41
|
+
needed it all along, and the bus uses it directly.
|
|
42
|
+
- **`PortManagement::PORT_TIMEOUT` is 45 seconds**, up from 30. A member that stops pinging
|
|
43
|
+
keeps its port 15 seconds longer.
|
|
44
|
+
- **`room_closed` always carries a reason.** In 0.6 a close the host decided (process exit,
|
|
45
|
+
watchdog timeout, lost lock) sent `reason: nil`; only `shutdown!` from inside the Room set one.
|
|
46
|
+
Now the runner sets it too: `"Server shutting down"`, `"Watchdog timeout"`, the signal name on
|
|
47
|
+
a `cable_room server` drain, and the failure on a migration that closed instead of moving.
|
|
48
|
+
- **Instrumentation payloads.** `error.cable_room` and the error handler get the new context
|
|
49
|
+
keys above. Every 0.6 event still fires with the same name.
|
|
50
|
+
|
|
51
|
+
### Added.
|
|
52
|
+
|
|
53
|
+
- `CableRoom.configure` / `CableRoom.config` (`CableRoom::Config`) with five knobs:
|
|
54
|
+
`room_host` (`:inline` | `:remote`), `broadcaster` (`:action_cable` | `:anycable`),
|
|
55
|
+
`provision_delay_ms` (20), `drain_timeout` (10 minutes), and `handoff_timeout` (10 seconds).
|
|
56
|
+
`CABLE_ROOM_HOST` and `CABLE_ROOM_BROADCASTER` override the first two, even when the block sets
|
|
57
|
+
them. Unknown values raise at boot and name the valid options. Defaults reproduce 0.6.
|
|
58
|
+
- `CableRoom::Broadcaster`: room→member traffic goes through `ActionCableBroadcaster`
|
|
59
|
+
(`ActionCable.server.broadcast`, the default) or `AnyCableBroadcaster` (`AnyCable.broadcast`).
|
|
60
|
+
Stream names are identical in both. `anycable-rails` is optional; selecting `:anycable`
|
|
61
|
+
without it raises `Broadcaster::MissingDependency` naming the gem.
|
|
62
|
+
- `CableRoom::Bus`: Redis pub/sub and the handoff storage on the `CABLEROOM_*` connection.
|
|
63
|
+
Channel names: `cr:{RoomClass:key}:in` (and `:in:{port}` for custom ports), `cr:provision`,
|
|
64
|
+
`cr:{RoomClass:key}:handoff`, `cr:{RoomClass:key}:snapshot`, `cr:{RoomClass:key}:adopted`.
|
|
65
|
+
`Room::Base.inbound_channel(key, port)` names a Room's inbound channel.
|
|
66
|
+
- `CableRoom::Host`: `Host.current` (nil when the process hosts nothing), `Host.instance`,
|
|
67
|
+
`Host.start!`, `Host#open_ports` (the load gauge to scale on), `Host#open_rooms_count`,
|
|
68
|
+
`Host#drain!`, `Host.after_drain`, `Host::NotHosting`.
|
|
69
|
+
- `cable_room server` (`exe/cable_room`, `CableRoom::CLI`): boots the Rails app in the current
|
|
70
|
+
directory (or `--require PATH`), refuses to run unless `room_host` is `:remote`, hosts Rooms
|
|
71
|
+
until SIGTERM or SIGINT, and migrates open Rooms to peers on the way out. `--workers N`
|
|
72
|
+
(default: core count) preloads the app and forks N single-GVL workers through
|
|
73
|
+
`Host::Supervisor`, which replaces a worker that dies (with a growing delay for one that dies
|
|
74
|
+
at boot), relays SIGTERM and SIGINT, and waits for every worker. `--version` prints the
|
|
75
|
+
version. `CableRoom.after_fork!` resets the bus, lock manager, Redis pool, and Host in a
|
|
76
|
+
forked child.
|
|
77
|
+
- Load-weighted provisioning (`CableRoom::Placement`): every host hears each `provision`
|
|
78
|
+
request, waits `provision_delay_ms × (open_rooms + jitter)`, then races for the Redlock.
|
|
79
|
+
Exactly one wins. A draining host never claims.
|
|
80
|
+
- Snapshot and restore: optional `snapshot_state` / `restore_state` hooks on a Room,
|
|
81
|
+
`restored?`, `CableRoom::Snapshot` (version 1, gem-owned ports, users, reaper deadlines, and
|
|
82
|
+
`app_state`), `Snapshot::NotSerializable` raised at snapshot time for non-JSON state, and
|
|
83
|
+
`Host#restore_room`. A restored Room runs `restore_state` instead of `startup` when it defines
|
|
84
|
+
it, and never broadcasts `room_opened`.
|
|
85
|
+
- Live migration on planned shutdown (`CableRoom::Migration`): freeze → snapshot → offer (Redis,
|
|
86
|
+
60 second TTL) → peer adopts → relay and replay with per-stream markers → let go. Members keep
|
|
87
|
+
their streams and lose nothing. A Room nobody adopts within `handoff_timeout` closes with
|
|
88
|
+
`room_closed`; `drain_timeout` forces whatever is still waiting through. New lifecycle states
|
|
89
|
+
`:freezing` and `:frozen`.
|
|
90
|
+
- Channel actions `hello` and `ping` on every `RoomMember` channel (and so on
|
|
91
|
+
`RoomProxyChannel`), plus the server-side `hello_room_memberships`, `RoomMembership#hello!`,
|
|
92
|
+
`#hello_received?`, `#accepts_input?`, and the protected `room_memberships` reader.
|
|
93
|
+
- AnyCable channel state: `CableRoom::MembershipStore` keeps each membership's identity in
|
|
94
|
+
anycable-rails' `state_attr_accessor`, so `hello`, `receive`, `ping`, and `unsubscribed` work
|
|
95
|
+
across anycable-rails' per-call channel instances. Under plain ActionCable nothing changes.
|
|
96
|
+
- New `ActiveSupport::Notifications` events: `hello_received.cable_room`,
|
|
97
|
+
`provision_requested.cable_room`, `provision_claimed.cable_room`, `room_snapshotted.cable_room`,
|
|
98
|
+
`room_restored.cable_room`, `host_draining.cable_room`, and `room_migrated.cable_room`.
|
|
99
|
+
- CI: an `e2e-anycable` job runs `spec/e2e` against a real `anycable/anycable-go:1.6` under both
|
|
100
|
+
Appraisals. Locally it runs only with `CABLE_ROOM_E2E=1`.
|
|
101
|
+
- `CHANGELOG.md` and `exe/` ship in the gem.
|
|
102
|
+
|
|
103
|
+
### Changed.
|
|
104
|
+
|
|
105
|
+
- `Room::Base.room_port_key` builds the stream name itself (`"RoomClass:key:port"`, records by
|
|
106
|
+
GlobalID). The format is the same one ActionCable produced in 0.6.
|
|
107
|
+
- The ActionCable `restart` hook (development code reload) stops Rooms through the Host.
|
|
108
|
+
- `RoomMembership#stream_port` takes `auto_close:`; the room-side `stream_port` takes `on_live:`.
|
|
109
|
+
- The `Railtie` no longer declares empty `rake_tasks`, `console`, and `runner` blocks.
|
|
110
|
+
- The README describes the 1.0 architecture: configuration, deployment modes, `cable_room
|
|
111
|
+
server`, provisioning, the hello handshake, AnyCable's browser contract, migration, every
|
|
112
|
+
instrumentation event, and the 0.6 → 1.0 upgrade guide.
|
|
113
|
+
|
|
114
|
+
### Fixed.
|
|
115
|
+
|
|
116
|
+
- The gemspec declares `redis`, which rediconn loads but never listed. An app that didn't have
|
|
117
|
+
`redis` in its own Gemfile could fail to boot with 0.6.
|
|
118
|
+
|
|
119
|
+
## 0.6.2.beta1
|
|
120
|
+
|
|
121
|
+
The last release before distributed rooms. Rooms ran inside a synthetic ActionCable channel in
|
|
122
|
+
every process that joined them.
|