monkrb 0.21.0 → 0.21.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 715184d6d6d9b3d6e50ab43d88d3c8ab7c56db310d0d30d90d67150b9dc28e0d
4
- data.tar.gz: 16265638cdde3786734a98c8bd0a743b26e4dca7ea3f253b74c32407ec0ae7f1
3
+ metadata.gz: fd1a1140ab4c223d2bdd9c10a226ea274e0051af1ab01444194cb4dc88ebb166
4
+ data.tar.gz: 9fab9365ba1a31224caf14038c2e36c0ba59c9cc70dd60c037f4dbfa78aec8c8
5
5
  SHA512:
6
- metadata.gz: '097a3550e18dfe987ade8ec24705073b1d0d129fa7303d557acf70ba896186c423d18bb780cbe1e2d6704d7ec8a3706ae163761b7e56225bf7fd651fe0f9163b'
7
- data.tar.gz: c1d3e26f194892e893fbdc92a30699fee4b2fbd0424a74bb063b5ca86eda29f76f4909f07e5c44d7211f78d242a1f01f6f36f3d356b37c203d861ffbba97bf83
6
+ metadata.gz: 36bf94be6268d9f12fbb703132f96b00a84c52e5eeb6b03d9b90b9e981d5c9be2ee89003ecc7952b2880d288454d4d6d1734ffb6cfd8bd70328dded0cbbc1e0e
7
+ data.tar.gz: 58c8a897231b31edcc82cfd0e3162c64633a2a121f2b3cc01dbbe3b2fa6ef7a7d9760eb2b623a4b6b8def85004322abba20b001758dadd291f8a2ada52b3d26b
data/CHANGELOG.md CHANGED
@@ -4,6 +4,28 @@ All notable changes to this project are documented here. Format is loosely
4
4
  [Keep a Changelog](https://keepachangelog.com/); versions are as released
5
5
  in `lib/monk/version.rb`.
6
6
 
7
+ ## 0.21.1 - 2026-10-09
8
+
9
+ ### Fixed
10
+
11
+ - **`monk add websocket --transport=postgres` publishes through the
12
+ `:notify` pool.** `config/websocket.rb` declares
13
+ `Monk::Persistence::Pg.pool(:notify, size: 1)` and builds
14
+ `PgFanout.new(..., db_pool: :notify)`, so a process holds one publishing
15
+ connection however many Ractors publish. Before, every `bin/server`
16
+ worker opened its own. `AppWebSocket.start!` starts the pool (with
17
+ Redis it does nothing): `config/load.rb` calls it at the end, which
18
+ covers `bin/server`, `bin/jobs`, `bin/console` and the tests, and
19
+ `bin/websocket_server` calls it too. An existing app: replace
20
+ `config/websocket.rb` with
21
+ `monk help websocket --file config/websocket.rb --transport=postgres`
22
+ and add the last lines of `monk help base --file config/load.rb`.
23
+ - **The scaffolded `Dockerfile` builds with `monk add postgres`.** Its
24
+ builder stage installs `build-essential`: `irb`'s dependencies (`erb`,
25
+ `io-console`, `prism`) compile native extensions. The image that runs
26
+ still has no compiler. An existing app: add the `apt-get` line from
27
+ `monk help base --file Dockerfile`.
28
+
7
29
  ## 0.21.0 - 2026-10-09
8
30
 
9
31
  ### Changed (breaking)
@@ -1,15 +1,19 @@
1
1
  # Two-stage build: the builder resolves and installs gems, the final image
2
2
  # only keeps the installed bundle plus the app -- no compiler, no gem
3
- # cache, in the image that actually runs. No system packages needed here:
4
- # kino ships as precompiled platform gems, and a plain `bundle install`
3
+ # cache, in the image that actually runs. The builder has a compiler for
4
+ # the gems that build a native extension (irb's dependencies, with monk
5
+ # add postgres); kino ships as precompiled platform gems, and pg 1.6+
6
+ # ships precompiled with its own libpq. A plain `bundle install`
5
7
  # (Gemfile.lock committed) already resolves every compatible platform, not
6
8
  # just the machine that ran it -- nothing to add by hand before building on
7
9
  # a different host (docs/guides/deploying.md, "Before the first build").
8
- # monk/rackup/webrick are pure Ruby, and pg (monk add postgres) 1.6+
9
- # ships precompiled with its own libpq.
10
10
  FROM ruby:4.0-slim AS builder
11
11
  WORKDIR /app
12
12
 
13
+ RUN apt-get update \
14
+ && apt-get install -y --no-install-recommends build-essential \
15
+ && rm -rf /var/lib/apt/lists/*
16
+
13
17
  COPY Gemfile Gemfile.lock* ./
14
18
  RUN bundle install
15
19
 
@@ -24,3 +24,9 @@ end
24
24
  %w[models presenters helpers mailers broadcasts jobs].each do |role|
25
25
  Dir[File.expand_path("../app/#{role}/**/*.rb", __dir__)].sort.each { |file| require file }
26
26
  end
27
+
28
+ # With websocket (monk add websocket), every process that loads this file
29
+ # can broadcast (bin/server, bin/jobs, bin/console, the tests), so its
30
+ # transport is started here, once everything above has declared its
31
+ # databases.
32
+ AppWebSocket.start! if defined?(AppWebSocket)
@@ -18,6 +18,9 @@ over the transport.
18
18
  body, never at a file's top level.
19
19
  - Only `bin/websocket_server` calls `listen!`; every other process only
20
20
  publishes.
21
+ - A process publishes only once `AppWebSocket.start!` has run:
22
+ `config/load.rb` calls it, so a script that loads `config/websocket.rb`
23
+ without it calls it itself, at boot, in the main Ractor.
21
24
  - With Postgres, a broadcast is capped at just under 8000 bytes (NOTIFY).
22
25
  - `WS_ALLOWED_ORIGINS` must list your pages' origins.
23
26
  - Switching transports is three steps in SETUP.md, websocket.
@@ -25,6 +25,10 @@ Monk::Bin.run(__FILE__) do
25
25
  exit 1
26
26
  end
27
27
 
28
+ # A socket's handler can broadcast too (the websocket-chat example does),
29
+ # so this process publishes like the others.
30
+ AppWebSocket.start!
31
+
28
32
  # This process holds the sockets, so it's the only one that listens for
29
33
  # what the others publish: the transport's subscriber connection opens
30
34
  # here, and an unreachable Postgres or Redis fails right here.
@@ -6,18 +6,32 @@ require_relative "persistence"
6
6
  # The WebSocket registry (monk add websocket): which sockets are subscribed
7
7
  # to which topics, and how a broadcast reaches them. bin/server, bin/jobs
8
8
  # and bin/websocket_server are separate processes, so Postgres
9
- # LISTEN/NOTIFY carries a broadcast from one to the others, over the
10
- # :primary connection's settings (config/persistence.rb). A broadcast is
11
- # capped at just under 8000 bytes, Postgres's NOTIFY limit. To switch to
12
- # Redis: SETUP.md, websocket.
9
+ # LISTEN/NOTIFY carries a broadcast from one to the others, on the
10
+ # :primary database (config/persistence.rb). A broadcast is capped at just
11
+ # under 8000 bytes, Postgres's NOTIFY limit. To switch to Redis: SETUP.md,
12
+ # websocket.
13
+ #
14
+ # Broadcasts are published through the :notify pool: one connection per
15
+ # process, however many Ractors publish. Size 1, so a page's updates are
16
+ # sent in the order they were made. Declaring it opens nothing:
17
+ # AppWebSocket.start! does, in every process that publishes (config/load.rb
18
+ # and bin/websocket_server call it).
19
+ Monk::Persistence::Pg.pool(:notify, size: 1)
20
+
13
21
  module AppWebSocket
14
22
  TRANSPORT = "postgres".freeze
15
23
 
16
24
  # A registry over this app's transport. bin/websocket_server's (REGISTRY)
17
- # also listens; every other process only publishes.
25
+ # also listens, on a connection of its own; every other process only
26
+ # publishes.
18
27
  def self.build_registry
19
- Monk::WebSocket::PgFanout.new(Monk::WebSocket::Registry.new,
20
- pg_opts: Monk::Persistence::Pg.connection_options(:primary),)
28
+ Monk::WebSocket::PgFanout.new(Monk::WebSocket::Registry.new, db_pool: :notify)
29
+ end
30
+
31
+ # Opens the :notify pool's connection. At boot, in the main Ractor, once
32
+ # every database and pool is declared.
33
+ def self.start!
34
+ Monk::Persistence::Pg.start_pools!(:notify)
21
35
  end
22
36
 
23
37
  REGISTRY = build_registry
@@ -17,5 +17,10 @@ module AppWebSocket
17
17
  Monk::WebSocket::RedisFanout.new(Monk::WebSocket::Registry.new, redis_url: Monk::Settings[:redis_url])
18
18
  end
19
19
 
20
+ # Nothing to open here: each publishing Ractor connects to Redis on its
21
+ # first broadcast. config/load.rb and bin/websocket_server call it all
22
+ # the same, as they would with Postgres.
23
+ def self.start!; end
24
+
20
25
  REGISTRY = build_registry
21
26
  end
@@ -24,11 +24,14 @@ connect with `wss://`.
24
24
 
25
25
  1. If the other one isn't installed, add it: `monk add redis` or
26
26
  `monk add postgres`.
27
- 2. In `config/websocket.rb`, swap the fanout: `Monk::WebSocket::RedisFanout`
28
- with `redis_url: Monk::Settings[:redis_url]` (and `require_relative
29
- "redis"`), or `Monk::WebSocket::PgFanout` with
30
- `pg_opts: Monk::Persistence::Pg.connection_options(:primary)` (and
31
- `require_relative "persistence"`).
27
+ 2. Replace `config/websocket.rb` with Monk's version for the other
28
+ transport (`redis` or `postgres`), then carry over anything you changed
29
+ in it:
30
+
31
+ ```bash
32
+ monk help websocket --file config/websocket.rb --transport=redis > config/websocket.rb
33
+ ```
34
+
32
35
  3. Restart `bin/server`, `bin/websocket_server` and `bin/jobs`.
33
36
 
34
37
  ### Check it works
data/lib/monk/version.rb CHANGED
@@ -5,5 +5,5 @@ module Monk
5
5
  # class of bug .freeze! guards against for routes/error handlers/models,
6
6
  # just on a top-level constant that every worker Ractor reads on boot
7
7
  # (found live under kino: GET /hello 500'd until this was frozen).
8
- VERSION = "0.21.0".freeze
8
+ VERSION = "0.21.1".freeze
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: monkrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.0
4
+ version: 0.21.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matteo Folin