deployangel 0.1.39 → 0.1.41

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: d930ff0701b6c48f6793339eaff985418ae4a6b0332689e7c87d85047f80a082
4
- data.tar.gz: a1848b93327d98249e6bd98acf595047b62b926604c9940ed92f17334db3b093
3
+ metadata.gz: 22f16a902fb53802309105722b669cc0be9e4a31c5938eb4aec2d99b8f0dab08
4
+ data.tar.gz: 6cdd96ff12a6e969afd80a23c0992c1a3139242ec3c3e9ec0c69e1b85309510a
5
5
  SHA512:
6
- metadata.gz: '00943ef2bac8f6acb697ec20243c211b96779b4eb33dc8c4da1aff53cd789b14ca569320fa06d960de7811a0dd15e4aacab06e6656f4ffe1240a8b63cf1467eb'
7
- data.tar.gz: 9e8ede3e14497f6afaf02b08f0438876397ee73b95f7ba79bbff8d43dc84ad69e018e0bffb903ce722458b1a5df48c2eb372580c034699a00315f09335a92235
6
+ metadata.gz: c38e4ab182cc8d3c657aeb4f6cb20e418223df54ba1faf515def863f3800035e58ad2a352dc67327f4bdbd6cb05a7a1f37f935669d49835e4fd8a77fa4a8c423
7
+ data.tar.gz: 18772b1f3c0f5eb84463fb3191a0509392f6ec5c5503b95aa1409cbc14bfc80ade81db82f7cb4f36fce679293fa591aebb5fed9bf22802e6a0f2e4b0c5913cb3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.41 (2026-11-04)
4
+
5
+ - The agent keeps an hour of unsent minutes (60 payloads, up from 10) when
6
+ DeployAngel can't be reached, so an outage of up to an hour loses no
7
+ telemetry. A minute that is lost leaves a gap DeployAngel has to learn
8
+ the app's normal traffic around. Kept gzipped, a full hour adds under
9
+ 1 MB at worst (`rake bench`). `config.max_queued_payloads` still sets it.
10
+
11
+ ## 0.1.40 (2026-11-04)
12
+
13
+ - Rails apps get two checkpoints with nothing to add: `rails.mail.delivered`,
14
+ counted from Action Mailer's deliveries, and `rails.storage.stored`, from
15
+ Active Storage's uploads. A release after which mail or uploads quietly
16
+ stop fails for it, the way a checkpoint the app records would. Counts
17
+ only: never a recipient, a filename, or a key. Off with
18
+ `config.derived_checkpoints = false` or
19
+ `DEPLOYANGEL_DERIVED_CHECKPOINTS=false`.
20
+
3
21
  ## 0.1.39 (2026-11-04)
4
22
 
5
23
  - `deployangel doctor` warns when the project's AGENTS.md or CLAUDE.md has
data/README.md CHANGED
@@ -185,8 +185,9 @@ user data.
185
185
  in-memory counters.
186
186
  - Payloads are sent from a background thread, once a minute, with short
187
187
  timeouts.
188
- - When DeployAngel is unreachable, the buffer is bounded (10 payloads, kept as
189
- gzipped JSON) and the oldest are dropped. Your app is never blocked or failed.
188
+ - When DeployAngel is unreachable, the buffer is bounded (60 payloads, an hour,
189
+ kept as gzipped JSON: under 1 MB at worst) and the oldest are dropped. Your
190
+ app is never blocked or failed.
190
191
  - Safe across forks (Puma cluster mode and similar), and the minute in progress
191
192
  is flushed at shutdown.
192
193
 
@@ -12,7 +12,7 @@ module DeployAngel
12
12
  attr_accessor :token, :endpoint, :enabled, :environments, :release_version, :revision,
13
13
  :flush_interval, :open_timeout, :read_timeout, :max_queued_payloads, :max_routes, :logger,
14
14
  :file_digests, :critical_flows, :ignored_routes, :sidekiq_cron_schedule_file, :exception_messages,
15
- :recurring_jobs
15
+ :recurring_jobs, :derived_checkpoints
16
16
 
17
17
  def initialize(env = ENV)
18
18
  @token = env["DEPLOYANGEL_TOKEN"]
@@ -24,7 +24,10 @@ module DeployAngel
24
24
  @flush_interval = 60
25
25
  @open_timeout = 2
26
26
  @read_timeout = 5
27
- @max_queued_payloads = 10
27
+ # An hour of minutes, gzipped (about 1 MB at worst), so an hour when
28
+ # DeployAngel can't be reached loses nothing. A lost minute leaves a
29
+ # gap the cloud learns the app's normal traffic around.
30
+ @max_queued_payloads = 60
28
31
  @max_routes = 100
29
32
  @logger = Logger.new($stderr, level: Logger::WARN, progname: "deployangel")
30
33
  @file_digests = parse_boolean(env["DEPLOYANGEL_FILE_DIGESTS"]) != false
@@ -43,6 +46,9 @@ module DeployAngel
43
46
  # cron line or Fugit's words ("every day at 4am"), optionally ending
44
47
  # in a time zone.
45
48
  @recurring_jobs = {}
49
+ # Checkpoints counted from Rails' own notifications, with nothing to
50
+ # add: mail delivered and files stored (DeployAngel::Rails::Checkpoints).
51
+ @derived_checkpoints = parse_boolean(env["DEPLOYANGEL_DERIVED_CHECKPOINTS"]) != false
46
52
  end
47
53
 
48
54
  # Reports only with a token, and by default in every environment but
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeployAngel
4
+ module Rails
5
+ # Checkpoints the app gets without adding a line (spec §17, Silent
6
+ # failures): mail delivered and files stored, counted from Rails' own
7
+ # notifications. Work that quietly stops is what verdicts miss most, and
8
+ # these two are where it most often stops. Counts only, never a
9
+ # recipient, a filename, or a key. Off with config.derived_checkpoints =
10
+ # false, or DEPLOYANGEL_DERIVED_CHECKPOINTS=false.
11
+ module Checkpoints
12
+ MAIL_DELIVERED = "rails.mail.delivered"
13
+ FILE_STORED = "rails.storage.stored"
14
+
15
+ def self.install
16
+ return if @installed
17
+
18
+ @installed = true
19
+ ::ActiveSupport::Notifications.subscribe("deliver.action_mailer") { DeployAngel.checkpoint(MAIL_DELIVERED) }
20
+ ::ActiveSupport::Notifications.subscribe("service_upload.active_storage") { DeployAngel.checkpoint(FILE_STORED) }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -9,6 +9,10 @@ module DeployAngel
9
9
  app.config.middleware.insert(0, DeployAngel::Rails::Http)
10
10
  end
11
11
 
12
+ initializer "deployangel.checkpoints" do
13
+ DeployAngel::Rails::Checkpoints.install if DeployAngel.configuration.derived_checkpoints
14
+ end
15
+
12
16
  initializer "deployangel.jobs" do
13
17
  ActiveSupport.on_load(:active_job) { DeployAngel::Rails::ActiveJob.install }
14
18
  DeployAngel::Sidekiq.install
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeployAngel
4
- VERSION = "0.1.39"
4
+ VERSION = "0.1.41"
5
5
  end
data/lib/deployangel.rb CHANGED
@@ -133,6 +133,7 @@ end
133
133
  require_relative "deployangel/rack/http"
134
134
  require_relative "deployangel/rails/http"
135
135
  require_relative "deployangel/rails/active_job"
136
+ require_relative "deployangel/rails/checkpoints"
136
137
  require_relative "deployangel/rails/error_subscriber"
137
138
  require_relative "deployangel/tasks"
138
139
  require_relative "deployangel/metadata"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deployangel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.39
4
+ version: 0.1.41
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Owens
@@ -60,6 +60,7 @@ files:
60
60
  - lib/deployangel/queue_backlog.rb
61
61
  - lib/deployangel/rack/http.rb
62
62
  - lib/deployangel/rails/active_job.rb
63
+ - lib/deployangel/rails/checkpoints.rb
63
64
  - lib/deployangel/rails/error_subscriber.rb
64
65
  - lib/deployangel/rails/http.rb
65
66
  - lib/deployangel/rails/metadata.rb