railwatch 0.3.4 → 0.3.6
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 +41 -2
- data/app/channels/railwatch/environment_channel.rb +17 -4
- data/app/jobs/railwatch/prune_telemetry_job.rb +20 -1
- data/app/models/railwatch/ingest/batch.rb +1 -1
- data/app/models/railwatch/ingest/mapper.rb +1 -3
- data/app/models/railwatch/telemetry_record.rb +48 -0
- data/db/railwatch_telemetry_migrate/20260903000000_enable_incremental_vacuum.rb +62 -0
- data/docs/embedded.md +64 -7
- data/docs/getting-started.md +0 -2
- data/docs/source-maps.md +1 -3
- data/lib/generators/railwatch/install/install_generator.rb +0 -8
- data/lib/railwatch/backtrace.rb +12 -2
- data/lib/railwatch/configuration.rb +6 -5
- data/lib/railwatch/engine.rb +2 -2
- data/lib/railwatch/export/client.rb +10 -3
- data/lib/railwatch/reporter.rb +2 -12
- data/lib/railwatch/source_maps.rb +13 -1
- data/lib/railwatch/spec_helper.rb +1 -1
- data/lib/railwatch/transport/http.rb +14 -5
- data/lib/railwatch/version.rb +1 -1
- data/lib/tasks/railwatch_tasks.rake +161 -0
- data/public/railwatch/assets/{app-layout-yh-sPWgK.js → app-layout-B5Fcdwfz.js} +1 -1
- data/public/railwatch/assets/{app-wordmark-nbjkzxwQ.js → app-wordmark-1SRllgHv.js} +1 -1
- data/public/railwatch/assets/{appearance-CDuRvQTB.js → appearance-DbwahDrc.js} +1 -1
- data/public/railwatch/assets/application-CwshqwM6.css +1 -0
- data/public/railwatch/assets/{arrow-up-DVtOGdVA.js → arrow-up-DwKQcab4.js} +1 -1
- data/public/railwatch/assets/{auth-layout-TCwPpS1K.js → auth-layout-DXfxXAN_.js} +1 -1
- data/public/railwatch/assets/{badge-Daw4Hvr8.js → badge-CApjyWcg.js} +1 -1
- data/public/railwatch/assets/{braces-DhFbHPsz.js → braces-kGSgxWnS.js} +1 -1
- data/public/railwatch/assets/{card-BX_3HXcJ.js → card-BaJ8kNkp.js} +1 -1
- data/public/railwatch/assets/{chart-B14-N9g7.js → chart-Xnrz1Nqw.js} +1 -1
- data/public/railwatch/assets/{chart-hover-Vy52H4uD.js → chart-hover-XYPNE2CX.js} +1 -1
- data/public/railwatch/assets/{chart-panel-Cb4S_ej_.js → chart-panel-BYk68mJJ.js} +1 -1
- data/public/railwatch/assets/{checkbox-D3aRSsBj.js → checkbox-Bf41R8W6.js} +1 -1
- data/public/railwatch/assets/{code-KvW8k7Jr.js → code-a-9sh36A.js} +1 -1
- data/public/railwatch/assets/{copy-block-BKFGd11J.js → copy-block-zykZWQym.js} +1 -1
- data/public/railwatch/assets/{copy-id-Djks1fXB.js → copy-id-b6CW5ESL.js} +1 -1
- data/public/railwatch/assets/{cursor-load-more-BXV0f1D_.js → cursor-load-more-0cHzbTPT.js} +1 -1
- data/public/railwatch/assets/{data-table-iv1bdF6u.js → data-table-IvA7xvrK.js} +1 -1
- data/public/railwatch/assets/{edit-BZc_Iawe.js → edit-7lmf3k80.js} +1 -1
- data/public/railwatch/assets/{edit-__9yJlO3.js → edit-DTtRV1fO.js} +1 -1
- data/public/railwatch/assets/{edit-DMKUF8Zi.js → edit-ZKE15r-F.js} +1 -1
- data/public/railwatch/assets/{empty-state-6j_0AaQQ.js → empty-state-BFTnQ2oT.js} +1 -1
- data/public/railwatch/assets/env-layout-erSDpIXg.js +1 -0
- data/public/railwatch/assets/{execution-path-CzgBUi5e.js → execution-path-Di5uUHi-.js} +1 -1
- data/public/railwatch/assets/{filter-bar-9SU5NrzX.js → filter-bar-Btm__gQi.js} +1 -1
- data/public/railwatch/assets/{flamegraph-qcekju8V.js → flamegraph-C-mZdqa7.js} +1 -1
- data/public/railwatch/assets/{frames-Cyu7KMxZ.js → frames-KZBsjg6-.js} +1 -1
- data/public/railwatch/assets/{google-sign-in-button-DsTSfmzY.js → google-sign-in-button-DJRoD72g.js} +1 -1
- data/public/railwatch/assets/index-9LL_C3eG.js +1 -0
- data/public/railwatch/assets/index-B-bSm1jB.js +1 -0
- data/public/railwatch/assets/{index-OqI59zPb.js → index-B0VXzXYG.js} +1 -1
- data/public/railwatch/assets/index-BAkZNNEh.js +1 -0
- data/public/railwatch/assets/{index-Cmlwy1-V.js → index-BWSyQRZI.js} +1 -1
- data/public/railwatch/assets/index-Bjw4sTXU.js +1 -0
- data/public/railwatch/assets/index-Bo8hrjbs.js +1 -0
- data/public/railwatch/assets/index-BoTOVM0v.js +1 -0
- data/public/railwatch/assets/index-Bot7kHMA.js +1 -0
- data/public/railwatch/assets/index-BsrCnQqg.js +1 -0
- data/public/railwatch/assets/index-BtSlLmkg.js +1 -0
- data/public/railwatch/assets/{index-BRiq3SNR.js → index-CAzQkw-h.js} +1 -1
- data/public/railwatch/assets/index-CBJZQgHA.js +1 -0
- data/public/railwatch/assets/index-CIUl9POV.js +1 -0
- data/public/railwatch/assets/{index-DlumCsWY.js → index-CP6jrrPT.js} +2 -2
- data/public/railwatch/assets/index-CU6yhEyt.js +1 -0
- data/public/railwatch/assets/{index-1ol1-QWI.js → index-CX8Br7m9.js} +1 -1
- data/public/railwatch/assets/index-CYYmZpZu.js +1 -0
- data/public/railwatch/assets/{index-DU9F5b5d.js → index-CeqMDByC.js} +1 -1
- data/public/railwatch/assets/index-Cj3_jD1E.js +1 -0
- data/public/railwatch/assets/index-D4968-TC.js +1 -0
- data/public/railwatch/assets/index-DAEzO_vq.js +1 -0
- data/public/railwatch/assets/index-DBTxQw77.js +1 -0
- data/public/railwatch/assets/index-DCAho97K.js +1 -0
- data/public/railwatch/assets/index-DEfu_YvU.js +1 -0
- data/public/railwatch/assets/{index-CeYKnapu.js → index-DXUwhSCQ.js} +1 -1
- data/public/railwatch/assets/index-DcItJxa5.js +1 -0
- data/public/railwatch/assets/index-EGU__DOB.js +1 -0
- data/public/railwatch/assets/index-HCJmFcZu.js +1 -0
- data/public/railwatch/assets/index-P_e_cI0O.js +1 -0
- data/public/railwatch/assets/index-QyHE9WsU.js +1 -0
- data/public/railwatch/assets/index-Z1c4nFL0.js +1 -0
- data/public/railwatch/assets/index-kNhZPLVj.js +1 -0
- data/public/railwatch/assets/index-uHBVO8Lh.js +1 -0
- data/public/railwatch/assets/index-wOj5j0KC.js +1 -0
- data/public/railwatch/assets/{inertia-TViv6kNv.js → inertia-Degv_G9N.js} +2 -2
- data/public/railwatch/assets/{input-error-LxImUkxv.js → input-error-C6SqO_iU.js} +1 -1
- data/public/railwatch/assets/{json-viewer-Ar4cjPDW.js → json-viewer-DcQIxT86.js} +1 -1
- data/public/railwatch/assets/klass-WgQEfWpo.js +1 -0
- data/public/railwatch/assets/{label-COUKWqE_.js → label-B_vK19tR.js} +1 -1
- data/public/railwatch/assets/{layout-DNSLAkw_.js → layout-C8q7GUlZ.js} +1 -1
- data/public/railwatch/assets/{live-dot-ChfUtY3p.js → live-dot-DaXEbkXo.js} +1 -1
- data/public/railwatch/assets/{nav-CNnDqPlm.js → nav-BnD5XArZ.js} +1 -1
- data/public/railwatch/assets/{new-Be55nmt9.js → new-BL9OqXHe.js} +1 -1
- data/public/railwatch/assets/{new-D05SajFR.js → new-BhRnQn4w.js} +1 -1
- data/public/railwatch/assets/{new-Bi_xQiIb.js → new-BqP0NhOF.js} +1 -1
- data/public/railwatch/assets/{new-BvCT8TMg.js → new-CWP3wtwt.js} +1 -1
- data/public/railwatch/assets/{new-D4uewYC8.js → new-DIjwu2jF.js} +1 -1
- data/public/railwatch/assets/{new-84S8ZJq9.js → new-uxMnBtoY.js} +1 -1
- data/public/railwatch/assets/{onboarding-CYZi5Cqc.js → onboarding-C_Y3xTsH.js} +1 -1
- data/public/railwatch/assets/{origin-identity-6q1-CBts.js → origin-identity-CNhOnfBa.js} +1 -1
- data/public/railwatch/assets/{percentile-picker-gFZCXtdb.js → percentile-picker-BujVEhP6.js} +1 -1
- data/public/railwatch/assets/{relative-time-IOOgl5n2.js → relative-time-6CoKr1lN.js} +1 -1
- data/public/railwatch/assets/release-health-1Qzc_XhT.js +1 -0
- data/public/railwatch/assets/route-xqgYjOwJ.js +1 -0
- data/public/railwatch/assets/{segmented-h1VdDTqE.js → segmented-CVKq2Xpa.js} +1 -1
- data/public/railwatch/assets/{select-_AJsUa7X.js → select-CsmSXsJ4.js} +1 -1
- data/public/railwatch/assets/{separator-BwwTYtCF.js → separator-CrM10Oot.js} +1 -1
- data/public/railwatch/assets/{series-chart-DaFPefku.js → series-chart-D33UhdG2.js} +1 -1
- data/public/railwatch/assets/{show-C8sHalnw.js → show-8H9WAGav.js} +1 -1
- data/public/railwatch/assets/show-9jDeBNpc.js +1 -0
- data/public/railwatch/assets/{show-DACku6AD.js → show-B0nHy31L.js} +3 -3
- data/public/railwatch/assets/{show-C4Ltf5i9.js → show-B3izvRdU.js} +1 -1
- data/public/railwatch/assets/show-B7NhcWgp.js +1 -0
- data/public/railwatch/assets/show-BM-E2iYc.js +1 -0
- data/public/railwatch/assets/show-BlNR3ZOZ.js +1 -0
- data/public/railwatch/assets/{show-DgSIoRvA.js → show-CJMeX75E.js} +1 -1
- data/public/railwatch/assets/{show-CeTL4B37.js → show-CMisHNAI.js} +2 -2
- data/public/railwatch/assets/{show-JxFtB4eK.js → show-CQ4Ze-Un.js} +2 -2
- data/public/railwatch/assets/{show-BM6X2Mpo.js → show-CvNV23gH.js} +1 -1
- data/public/railwatch/assets/show-DMZlwzL_.js +1 -0
- data/public/railwatch/assets/show-DUwQlohF.js +1 -0
- data/public/railwatch/assets/{show-DIOSGcXV.js → show-DZwcZZrz.js} +2 -2
- data/public/railwatch/assets/show-ixK2r2f1.js +1 -0
- data/public/railwatch/assets/{show-DYteoYWW.js → show-rysBbvt-.js} +1 -1
- data/public/railwatch/assets/show-zxVxhUel.js +1 -0
- data/public/railwatch/assets/{sort-header-DpFzXblu.js → sort-header-CKj_7G3U.js} +1 -1
- data/public/railwatch/assets/{sparkline-cell-C3-5vFkP.js → sparkline-cell-Ckg29yVq.js} +1 -1
- data/public/railwatch/assets/stat-TxvoBiC8.js +1 -0
- data/public/railwatch/assets/{status-badge-8jVV-LA4.js → status-badge-5NCVJHjo.js} +1 -1
- data/public/railwatch/assets/{tenant-path-G-6u9A-o.js → tenant-path-B5ZRK4x3.js} +1 -1
- data/public/railwatch/assets/{text-link-DfsiaCcP.js → text-link-BPllRj0F.js} +1 -1
- data/public/railwatch/assets/{textarea-Dye72uP7.js → textarea-DtD5yZp_.js} +1 -1
- data/public/railwatch/assets/{timeline-CD7WHnbo.js → timeline-DZz5ZnHN.js} +1 -1
- data/public/railwatch/assets/{transition-B_AW8rMK.js → transition-Ds6Cakuc.js} +1 -1
- data/public/railwatch/assets/{use-clipboard-ColgLyQ2.js → use-clipboard-BLjjYH8V.js} +1 -1
- data/public/railwatch/assets/use-live-GKze1mNC.js +1 -0
- data/public/railwatch/manifest.json +1291 -1238
- metadata +117 -115
- data/public/railwatch/assets/application-DD4nJA5I.css +0 -1
- data/public/railwatch/assets/env-layout-DrT8rO6P.js +0 -1
- data/public/railwatch/assets/index-5jI4aFzC.js +0 -1
- data/public/railwatch/assets/index-9KTrVnrc.js +0 -1
- data/public/railwatch/assets/index-B0-8lcTp.js +0 -1
- data/public/railwatch/assets/index-B7jjfNfO.js +0 -1
- data/public/railwatch/assets/index-BBchRy0M.js +0 -1
- data/public/railwatch/assets/index-BgKj9xhr.js +0 -1
- data/public/railwatch/assets/index-BkTZqqOu.js +0 -1
- data/public/railwatch/assets/index-BprKx8QO.js +0 -1
- data/public/railwatch/assets/index-C3jzvPs3.js +0 -1
- data/public/railwatch/assets/index-Cbs6gGyQ.js +0 -1
- data/public/railwatch/assets/index-CdRZ6AWF.js +0 -1
- data/public/railwatch/assets/index-Cwx6058d.js +0 -1
- data/public/railwatch/assets/index-D4CSdbHv.js +0 -1
- data/public/railwatch/assets/index-DEFMSkdG.js +0 -1
- data/public/railwatch/assets/index-DFiHEBSh.js +0 -1
- data/public/railwatch/assets/index-DL4vWdWJ.js +0 -1
- data/public/railwatch/assets/index-DaXgPcGL.js +0 -1
- data/public/railwatch/assets/index-DbtaU-EE.js +0 -1
- data/public/railwatch/assets/index-DeOe83F4.js +0 -1
- data/public/railwatch/assets/index-DiucHN4B.js +0 -1
- data/public/railwatch/assets/index-DlnR_l9o.js +0 -1
- data/public/railwatch/assets/index-DmRd7aIG.js +0 -1
- data/public/railwatch/assets/index-DxSh2UpM.js +0 -1
- data/public/railwatch/assets/index-MIMGuFNt.js +0 -1
- data/public/railwatch/assets/index-P4rC7IlX.js +0 -1
- data/public/railwatch/assets/index-gpPOcFWq.js +0 -1
- data/public/railwatch/assets/index-oVkururr.js +0 -1
- data/public/railwatch/assets/index-p9puqVge.js +0 -1
- data/public/railwatch/assets/klass-CJ-J4INB.js +0 -1
- data/public/railwatch/assets/release-health-DC8oc7uw.js +0 -1
- data/public/railwatch/assets/route-Dv6LAWvT.js +0 -1
- data/public/railwatch/assets/show-B7NCgkEo.js +0 -1
- data/public/railwatch/assets/show-BKqyKjBK.js +0 -1
- data/public/railwatch/assets/show-BNw4tN5q.js +0 -1
- data/public/railwatch/assets/show-BO3bnG5h.js +0 -1
- data/public/railwatch/assets/show-BhrAVAEA.js +0 -1
- data/public/railwatch/assets/show-CpfgV1jP.js +0 -1
- data/public/railwatch/assets/show-DQp_1n-B.js +0 -1
- data/public/railwatch/assets/show-DVNz46RI.js +0 -1
- data/public/railwatch/assets/stat-s4RpOS9w.js +0 -1
data/lib/railwatch/version.rb
CHANGED
|
@@ -28,6 +28,130 @@ module Railwatch
|
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
# What the embedded telemetry database is costing on disk, and the one-time
|
|
32
|
+
# conversion that lets pruning give that cost back.
|
|
33
|
+
#
|
|
34
|
+
# Deleting rows does not shrink a SQLite file. The pages go on the freelist
|
|
35
|
+
# and are reused by later inserts, and the only way back to the filesystem
|
|
36
|
+
# is auto_vacuum=incremental plus PRAGMA incremental_vacuum -- which
|
|
37
|
+
# PruneTelemetryJob now runs after every prune. A database can only enter
|
|
38
|
+
# that mode while it is still empty (EnableIncrementalVacuum does that for
|
|
39
|
+
# every telemetry database created since it shipped) or through a full
|
|
40
|
+
# VACUUM, which is what this offers to an older one.
|
|
41
|
+
class TelemetryDisk
|
|
42
|
+
# Deliberately pessimistic, and said out loud as an estimate: VACUUM
|
|
43
|
+
# rewrites the whole file, and what that costs is the operator's disk,
|
|
44
|
+
# not ours to know.
|
|
45
|
+
VACUUM_BYTES_PER_SECOND = 50 * 1024 * 1024
|
|
46
|
+
|
|
47
|
+
# nil, having said why, for an install with no telemetry database to
|
|
48
|
+
# talk about.
|
|
49
|
+
def self.open
|
|
50
|
+
unless Railwatch.config.local?
|
|
51
|
+
puts "Railwatch reports over HTTP here (transport = :http), so this app has no telemetry database; nothing to vacuum."
|
|
52
|
+
return nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
environment = Railwatch::Environment.current
|
|
56
|
+
return new(environment) if environment.with_telemetry { Railwatch::TelemetryRecord.sqlite? }
|
|
57
|
+
|
|
58
|
+
puts "The railwatch_telemetry database is not SQLite; auto_vacuum does not apply."
|
|
59
|
+
nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def initialize(environment)
|
|
63
|
+
@environment = environment
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def report
|
|
67
|
+
with_telemetry do
|
|
68
|
+
<<~TEXT.chomp
|
|
69
|
+
Railwatch telemetry database
|
|
70
|
+
file #{path}
|
|
71
|
+
size #{human(file_bytes)}#{" + #{human(wal_bytes)} WAL" if wal_bytes.positive?}
|
|
72
|
+
mode auto_vacuum=#{mode}
|
|
73
|
+
free #{freelist} pages (#{human(freelist * page_size)}) on the freelist
|
|
74
|
+
TEXT
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def advice
|
|
79
|
+
with_telemetry do
|
|
80
|
+
if mode != :incremental
|
|
81
|
+
"\nPruning cannot return space to the filesystem in this mode: every page it frees stays in this file.\n" \
|
|
82
|
+
"`bin/rails railwatch:vacuum` converts the database to incremental auto-vacuum with a full VACUUM. " \
|
|
83
|
+
"That rewrites all #{human(file_bytes)}, needs about that much free disk for the temporary copy, and " \
|
|
84
|
+
"holds the write lock for roughly #{estimate}. Telemetry written while it runs waits for it."
|
|
85
|
+
elsif freelist.positive?
|
|
86
|
+
"\nThe nightly prune returns up to #{human(Railwatch::PruneTelemetryJob::VACUUM_PAGES_PER_SLICE * Railwatch::PruneTelemetryJob::VACUUM_SLICES * page_size)} " \
|
|
87
|
+
"a night on its own. `bin/rails railwatch:vacuum` returns all #{human(freelist * page_size)} now."
|
|
88
|
+
else
|
|
89
|
+
"\nNothing on the freelist: pruning is already returning this database's space as it goes."
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# The whole point of asking explicitly, so this one is not bounded the way
|
|
95
|
+
# the nightly prune is.
|
|
96
|
+
def reclaim!
|
|
97
|
+
with_telemetry do
|
|
98
|
+
before = disk_bytes
|
|
99
|
+
if mode == :incremental
|
|
100
|
+
Railwatch::TelemetryRecord.incremental_vacuum
|
|
101
|
+
else
|
|
102
|
+
puts "\nConverting to incremental auto-vacuum (full VACUUM, roughly #{estimate})..."
|
|
103
|
+
connection.execute("PRAGMA auto_vacuum = incremental")
|
|
104
|
+
connection.execute("VACUUM")
|
|
105
|
+
end
|
|
106
|
+
# A checkpoint that cannot finish says so in its result rather than
|
|
107
|
+
# raising: a reader still on an older snapshot holds the WAL open.
|
|
108
|
+
# Counting only the main file would then report the WAL's bytes as
|
|
109
|
+
# returned while they are still on the disk.
|
|
110
|
+
busy = checkpoint_busy?
|
|
111
|
+
[
|
|
112
|
+
"\nauto_vacuum=#{mode}, #{human(disk_bytes)} on disk including the WAL " \
|
|
113
|
+
"(#{human(before - disk_bytes)} returned), #{freelist} pages left on the freelist.",
|
|
114
|
+
busy ? "The WAL could not be truncated yet -- something is still reading it. " \
|
|
115
|
+
"Its bytes come back at the next checkpoint; run this again if you want to watch it." : nil
|
|
116
|
+
].compact.join("\n")
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
private
|
|
121
|
+
def with_telemetry(&) = @environment.with_telemetry(&)
|
|
122
|
+
|
|
123
|
+
def connection = Railwatch::TelemetryRecord.connection
|
|
124
|
+
|
|
125
|
+
def mode = Railwatch::TelemetryRecord.auto_vacuum_mode
|
|
126
|
+
|
|
127
|
+
def freelist = Railwatch::TelemetryRecord.freelist_pages
|
|
128
|
+
|
|
129
|
+
def page_size = Railwatch::TelemetryRecord.page_size
|
|
130
|
+
|
|
131
|
+
def path = Rails.root.join(Railwatch::TelemetryRecord.connection_db_config.database.to_s)
|
|
132
|
+
|
|
133
|
+
def file_bytes = File.exist?(path) ? File.size(path) : 0
|
|
134
|
+
|
|
135
|
+
# What this database actually occupies. In WAL mode the pages a VACUUM
|
|
136
|
+
# frees are not off the disk until the WAL is checkpointed, so the main
|
|
137
|
+
# file alone understates it -- and, right after a vacuum, flatters it.
|
|
138
|
+
def disk_bytes = file_bytes + wal_bytes
|
|
139
|
+
|
|
140
|
+
# `PRAGMA wal_checkpoint` answers with [busy, log_pages, checkpointed];
|
|
141
|
+
# a non-zero first column means it gave up rather than failed.
|
|
142
|
+
def checkpoint_busy?
|
|
143
|
+
connection.select_rows("PRAGMA wal_checkpoint(TRUNCATE)").dig(0, 0).to_i != 0
|
|
144
|
+
rescue StandardError
|
|
145
|
+
false
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def wal_bytes = File.exist?("#{path}-wal") ? File.size("#{path}-wal") : 0
|
|
149
|
+
|
|
150
|
+
def estimate = ActiveSupport::Duration.build([ (file_bytes / VACUUM_BYTES_PER_SECOND.to_f).ceil, 1 ].max).inspect
|
|
151
|
+
|
|
152
|
+
def human(bytes) = ActiveSupport::NumberHelper.number_to_human_size(bytes)
|
|
153
|
+
end
|
|
154
|
+
|
|
31
155
|
# Where this install's platform lives, derived from config.ingest_url:
|
|
32
156
|
# railwatch:token and railwatch:mcp point at the same host the gem already
|
|
33
157
|
# ships to, so a self-hosted app never gets told to visit railwatch.rebulk.com.
|
|
@@ -127,6 +251,25 @@ namespace :railwatch do
|
|
|
127
251
|
else "cannot check: #{pending}"
|
|
128
252
|
end, fatal: true)
|
|
129
253
|
end
|
|
254
|
+
# An install created before 0.3.5 is in auto_vacuum=none, where the
|
|
255
|
+
# nightly prune's reclaim is a silent no-op and the file only grows.
|
|
256
|
+
# Nothing converts it on its own, because that needs a full VACUUM with
|
|
257
|
+
# the write lock held -- so the check people actually run is where it
|
|
258
|
+
# has to be said, rather than leaving them to notice the disk.
|
|
259
|
+
if Railwatch.config.local? && Railwatch::TelemetryRecord.sqlite?
|
|
260
|
+
vacuum_mode = begin
|
|
261
|
+
Railwatch::Environment.current.with_telemetry { Railwatch::TelemetryRecord.auto_vacuum_mode }
|
|
262
|
+
rescue StandardError => e
|
|
263
|
+
e.message
|
|
264
|
+
end
|
|
265
|
+
check.call(vacuum_mode == :incremental, "telemetry disk",
|
|
266
|
+
case vacuum_mode
|
|
267
|
+
when :incremental then "auto_vacuum=incremental; the nightly prune returns freed pages"
|
|
268
|
+
when Symbol then "auto_vacuum=#{vacuum_mode}: pruned pages stay in the file " \
|
|
269
|
+
"(bin/rails railwatch:vacuum:status)"
|
|
270
|
+
else "cannot check: #{vacuum_mode}"
|
|
271
|
+
end)
|
|
272
|
+
end
|
|
130
273
|
# The maintenance clock runs in web and worker processes, not in this
|
|
131
274
|
# rake process, so what can be checked here is whether one has ticked.
|
|
132
275
|
last_tick = begin
|
|
@@ -297,6 +440,24 @@ namespace :railwatch do
|
|
|
297
440
|
puts "\nRailwatch is wired up."
|
|
298
441
|
end
|
|
299
442
|
|
|
443
|
+
# Disk. `railwatch:vacuum:status` only reads; `railwatch:vacuum` is the
|
|
444
|
+
# one-time conversion a database created before EnableIncrementalVacuum
|
|
445
|
+
# needs, and it is a rake task rather than anything automatic because it
|
|
446
|
+
# rewrites the whole file with the write lock held.
|
|
447
|
+
desc "Report the telemetry database's size, free pages, and whether pruning can return them to the filesystem"
|
|
448
|
+
task "vacuum:status" => :environment do
|
|
449
|
+
disk = Railwatch::TelemetryDisk.open or next
|
|
450
|
+
puts disk.report
|
|
451
|
+
puts disk.advice
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
desc "Reclaim disk from the telemetry database. Converts it to incremental auto-vacuum if needed -- a full VACUUM, which locks the file"
|
|
455
|
+
task vacuum: :environment do
|
|
456
|
+
disk = Railwatch::TelemetryDisk.open or next
|
|
457
|
+
puts disk.report
|
|
458
|
+
puts disk.reclaim!
|
|
459
|
+
end
|
|
460
|
+
|
|
300
461
|
namespace :export do
|
|
301
462
|
desc "Show what the export queue is holding and whether it can send"
|
|
302
463
|
task status: :environment do
|