trellis-pg 0.1.0.pre.beta → 0.1.0.pre.gamma
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/README.md +30 -0
- data/ext/trellis_ruby/Cargo.lock +5 -5
- data/ext/trellis_ruby/Cargo.toml +3 -3
- data/ext/trellis_ruby/src/lib.rs +15 -0
- data/lib/trellis/metrics.rb +38 -0
- data/lib/trellis/pg.rb +2 -0
- data/lib/trellis/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8839af0acc8f206000a1348bbba21b4ea1d06784bf7d677c0244f0c630863c00
|
|
4
|
+
data.tar.gz: 77f8ffb6fc607c81fcbb614a6238aa9c21770616a525aeda1df4a007247c0d59
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fc0f00f2deb17dcbb647ca2ff60d0da513e77987fc9d4206cf1c4f723412284d44f337120dc1c667a7d6149a07f144d97825a6f9cf473d2f1c3f18630e5c1e00
|
|
7
|
+
data.tar.gz: 8c00d355d02a8437815fedfa97e519c4ce2fe576e46a4614c273bd1c290c89729bc1f83e1c0176b315f5a26a1566ab74a01b5453b59f25a411308e415c93674e
|
data/README.md
CHANGED
|
@@ -103,6 +103,9 @@ Nothing in the binding uses it.
|
|
|
103
103
|
and `self_check_job` returns `nil` for the replaced job or one whose
|
|
104
104
|
transform was dropped. With no drain worker anywhere in the fleet a job
|
|
105
105
|
stays `:queued`.
|
|
106
|
+
- `Trellis::Metrics.render_prometheus`: the process-wide metrics registry as
|
|
107
|
+
Prometheus text, for a `/metrics` route the app already serves (the
|
|
108
|
+
binding opens no port; see [Metrics](#metrics)). It needs no handle.
|
|
106
109
|
|
|
107
110
|
```ruby
|
|
108
111
|
require "trellis/pg"
|
|
@@ -172,6 +175,32 @@ Every handle (each `Trellis::Instance` too) costs this again. The full
|
|
|
172
175
|
accounting is in
|
|
173
176
|
[`docs/embedding.md`](../../docs/embedding.md#what-a-handle-uses).
|
|
174
177
|
|
|
178
|
+
### Metrics
|
|
179
|
+
|
|
180
|
+
The engine's metrics live in one registry per process, holding the series of
|
|
181
|
+
every handle in it; `Trellis::Metrics.render_prometheus` renders them in
|
|
182
|
+
Prometheus's text format. Every series carries a `trellis_instance` label
|
|
183
|
+
(`<database>/<catalog schema>`), so instances in one process stay apart, and
|
|
184
|
+
`trellis_instance_up` is 1 while an instance's handle runs and 0 after it
|
|
185
|
+
shuts down. The metrics themselves are listed in
|
|
186
|
+
[`docs/observability.md`](../../docs/observability.md).
|
|
187
|
+
|
|
188
|
+
The binding opens no port, so serve the text from a route of the app's own:
|
|
189
|
+
|
|
190
|
+
```ruby
|
|
191
|
+
# config/routes.rb
|
|
192
|
+
get "/metrics", to: proc {
|
|
193
|
+
[200, { "content-type" => "text/plain; version=0.0.4" }, [Trellis::Metrics.render_prometheus]]
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Under a forking server each worker process has its own registry, holding
|
|
198
|
+
only its own handles' series, so Prometheus scrapes each worker (or the
|
|
199
|
+
worker handle, `staging: true`, runs in a process of its own that it
|
|
200
|
+
scrapes). A process forked while its parent had a handle running can't
|
|
201
|
+
render the registry, as it can't connect: it raises
|
|
202
|
+
`Trellis::ForkedHandleError` (see [Forking servers](#forking-servers)).
|
|
203
|
+
|
|
175
204
|
### Several instances
|
|
176
205
|
|
|
177
206
|
A process can hold several Trellis instances, for different catalog schemas
|
|
@@ -524,6 +553,7 @@ source rows; a test database has none, so that is immediate. Runtime state
|
|
|
524
553
|
## Layout
|
|
525
554
|
|
|
526
555
|
- `lib/`: the `Trellis` module and `Trellis::Instance`, its error classes and its `Data` values,
|
|
556
|
+
`Trellis::Metrics`,
|
|
527
557
|
the Rails integration (`trellis/railtie.rb`, `trellis/migration.rb`),
|
|
528
558
|
loaded only in an app that has Rails, and the test helpers
|
|
529
559
|
(`trellis/test_support.rb`), loaded only when required.
|
data/ext/trellis_ruby/Cargo.lock
CHANGED
|
@@ -1729,8 +1729,8 @@ dependencies = [
|
|
|
1729
1729
|
|
|
1730
1730
|
[[package]]
|
|
1731
1731
|
name = "trellis"
|
|
1732
|
-
version = "0.1.0-
|
|
1733
|
-
source = "git+https://github.com/salesforce-misc/trellis?rev=
|
|
1732
|
+
version = "0.1.0-gamma"
|
|
1733
|
+
source = "git+https://github.com/salesforce-misc/trellis?rev=c271ef149159d9309174ca476d792c89128bce99#c271ef149159d9309174ca476d792c89128bce99"
|
|
1734
1734
|
dependencies = [
|
|
1735
1735
|
"deadpool",
|
|
1736
1736
|
"deadpool-postgres",
|
|
@@ -1752,8 +1752,8 @@ dependencies = [
|
|
|
1752
1752
|
|
|
1753
1753
|
[[package]]
|
|
1754
1754
|
name = "trellis-embed"
|
|
1755
|
-
version = "0.1.0-
|
|
1756
|
-
source = "git+https://github.com/salesforce-misc/trellis?rev=
|
|
1755
|
+
version = "0.1.0-gamma"
|
|
1756
|
+
source = "git+https://github.com/salesforce-misc/trellis?rev=c271ef149159d9309174ca476d792c89128bce99#c271ef149159d9309174ca476d792c89128bce99"
|
|
1757
1757
|
dependencies = [
|
|
1758
1758
|
"tracing",
|
|
1759
1759
|
"trellis",
|
|
@@ -1761,7 +1761,7 @@ dependencies = [
|
|
|
1761
1761
|
|
|
1762
1762
|
[[package]]
|
|
1763
1763
|
name = "trellis_ruby"
|
|
1764
|
-
version = "0.1.0-
|
|
1764
|
+
version = "0.1.0-gamma"
|
|
1765
1765
|
dependencies = [
|
|
1766
1766
|
"magnus",
|
|
1767
1767
|
"rb-sys",
|
data/ext/trellis_ruby/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "trellis_ruby"
|
|
3
|
-
version = "0.1.0-
|
|
3
|
+
version = "0.1.0-gamma"
|
|
4
4
|
edition = "2024"
|
|
5
5
|
publish = false
|
|
6
6
|
|
|
@@ -28,8 +28,8 @@ doctest = false
|
|
|
28
28
|
ruby = ["dep:magnus", "dep:rb-sys"]
|
|
29
29
|
|
|
30
30
|
[dependencies]
|
|
31
|
-
trellis = { git = "https://github.com/salesforce-misc/trellis", rev = "
|
|
32
|
-
trellis-embed = { git = "https://github.com/salesforce-misc/trellis", rev = "
|
|
31
|
+
trellis = { git = "https://github.com/salesforce-misc/trellis", rev = "c271ef149159d9309174ca476d792c89128bce99" }
|
|
32
|
+
trellis-embed = { git = "https://github.com/salesforce-misc/trellis", rev = "c271ef149159d9309174ca476d792c89128bce99" }
|
|
33
33
|
magnus = { version = "0.9", optional = true, default-features = false, features = ["rb-sys"] }
|
|
34
34
|
rb-sys = { version = "0.9", optional = true }
|
|
35
35
|
|
data/ext/trellis_ruby/src/lib.rs
CHANGED
|
@@ -1231,6 +1231,20 @@ fn statement_kinds() -> Vec<&'static str> {
|
|
|
1231
1231
|
.collect()
|
|
1232
1232
|
}
|
|
1233
1233
|
|
|
1234
|
+
/// The process-wide metrics registry in Prometheus text exposition format:
|
|
1235
|
+
/// `trellis::Metrics::render_prometheus`, the series of every handle in this
|
|
1236
|
+
/// process. It needs no handle.
|
|
1237
|
+
///
|
|
1238
|
+
/// The registry sits behind a lock the engine's threads take, so a process
|
|
1239
|
+
/// forked while its parent had an engine running may have inherited it held:
|
|
1240
|
+
/// rendering there raises `Trellis::ForkedHandleError`, as [`connect`] does,
|
|
1241
|
+
/// rather than risk the hang. Rendering is a short walk of the registry,
|
|
1242
|
+
/// so it keeps the GVL.
|
|
1243
|
+
fn render_prometheus(ruby: &Ruby) -> Result<String, Error> {
|
|
1244
|
+
engine::check().map_err(|err| forked_handle_error(ruby, forked_while_running(&err)))?;
|
|
1245
|
+
Ok(trellis::Metrics::new().render_prometheus())
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1234
1248
|
#[magnus::init]
|
|
1235
1249
|
fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
1236
1250
|
// Interns every symbol a result can carry up front, from the closed
|
|
@@ -1252,6 +1266,7 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
1252
1266
|
native.define_module_function("capture_failure_kinds", function!(capture_failure_kinds, 0))?;
|
|
1253
1267
|
native.define_module_function("index_roles", function!(index_roles, 0))?;
|
|
1254
1268
|
native.define_module_function("statement_kinds", function!(statement_kinds, 0))?;
|
|
1269
|
+
native.define_module_function("render_prometheus", function!(render_prometheus, 0))?;
|
|
1255
1270
|
|
|
1256
1271
|
let handle = native.define_class("Handle", ruby.class_object())?;
|
|
1257
1272
|
handle.define_method("owner_pid", method!(Handle::owner_pid, 0))?;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Trellis
|
|
4
|
+
# The engine's metrics, in Prometheus text exposition format: the Rust
|
|
5
|
+
# crate's trellis::Metrics#render_prometheus
|
|
6
|
+
# (docs/decisions/0009-observability-decisions.md).
|
|
7
|
+
#
|
|
8
|
+
# The registry is process-wide: one body holds the series of every Trellis
|
|
9
|
+
# handle in this process, so it needs no handle and works before
|
|
10
|
+
# Trellis.connect and after Trellis.shutdown. Every series carries a
|
|
11
|
+
# trellis_instance="<database>/<catalog schema>" label, so instances in one
|
|
12
|
+
# process stay apart. trellis_instance_up is 1 while an instance has a
|
|
13
|
+
# running handle and 0 after its last one shuts down; the other gauges of a
|
|
14
|
+
# stopped instance disappear after 60 seconds. See docs/observability.md.
|
|
15
|
+
#
|
|
16
|
+
# The binding opens no port. Serve the text from a route the app already
|
|
17
|
+
# has, for example in Rails:
|
|
18
|
+
#
|
|
19
|
+
# # config/routes.rb
|
|
20
|
+
# get "/metrics", to: proc {
|
|
21
|
+
# [200, { "content-type" => "text/plain; version=0.0.4" }, [Trellis::Metrics.render_prometheus]]
|
|
22
|
+
# }
|
|
23
|
+
#
|
|
24
|
+
# In a forking server each worker process has its own registry, holding
|
|
25
|
+
# only its own handles' series, so scrape every worker (or run the worker
|
|
26
|
+
# handle, staging: true, in a process of its own and scrape that).
|
|
27
|
+
#
|
|
28
|
+
# A process forked while its parent had an engine running may have
|
|
29
|
+
# inherited the registry's lock held, so rendering there raises
|
|
30
|
+
# Trellis::ForkedHandleError, as Trellis.connect does.
|
|
31
|
+
module Metrics
|
|
32
|
+
# Renders the registry's current contents: # HELP and # TYPE lines, then
|
|
33
|
+
# each series' samples.
|
|
34
|
+
def self.render_prometheus
|
|
35
|
+
Native.render_prometheus
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/trellis/pg.rb
CHANGED
|
@@ -24,6 +24,7 @@ else
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
require_relative "instance"
|
|
27
|
+
require_relative "metrics"
|
|
27
28
|
|
|
28
29
|
# Embedded Trellis for Ruby apps: a native extension over the `trellis`
|
|
29
30
|
# crate's BlockingTrellis, so a Rails app can define and run streaming
|
|
@@ -48,6 +49,7 @@ require_relative "instance"
|
|
|
48
49
|
# - Operations: request_backfill, detect_capture_disruptions, has_live_drain_workers?,
|
|
49
50
|
# has_live_staging_worker?, watermark_token, await_converged, self_check,
|
|
50
51
|
# self_check_job.
|
|
52
|
+
# - Metrics: Trellis::Metrics.render_prometheus, which needs no handle.
|
|
51
53
|
#
|
|
52
54
|
# # A deploy's migration step: the defaults run nothing in the background.
|
|
53
55
|
# Trellis.connect(url: "host=localhost dbname=app")
|
data/lib/trellis/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: trellis-pg
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.0.pre.
|
|
4
|
+
version: 0.1.0.pre.gamma
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Salesforce
|
|
@@ -41,6 +41,7 @@ files:
|
|
|
41
41
|
- ext/trellis_ruby/src/lib.rs
|
|
42
42
|
- lib/trellis/error.rb
|
|
43
43
|
- lib/trellis/instance.rb
|
|
44
|
+
- lib/trellis/metrics.rb
|
|
44
45
|
- lib/trellis/migration.rb
|
|
45
46
|
- lib/trellis/pg.rb
|
|
46
47
|
- lib/trellis/railtie.rb
|