From 4749020bc34c0367d9a78e804a7ccf682e5332c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Sun, 27 Sep 2026 16:08:48 +0200 Subject: [PATCH] Cache reports by hledger version --- app/controllers/hledger/reports_controller.rb | 8 +++++--- lib/hledger/runner.rb | 16 +++++++++++++++- spec/requests/hledger/reports_spec.rb | 10 ++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/app/controllers/hledger/reports_controller.rb b/app/controllers/hledger/reports_controller.rb index 05579d0..7676367 100644 --- a/app/controllers/hledger/reports_controller.rb +++ b/app/controllers/hledger/reports_controller.rb @@ -28,7 +28,8 @@ module ::Hledger end first_post = @topic.first_post - cache_key = cache_key_for(first_post, report_type, begin_date, end_date) + runner = Hledger::Runner.new + cache_key = cache_key_for(runner, first_post, report_type, begin_date, end_date) if (cached = Discourse.cache.read(cache_key)) return render(json: cached) @@ -41,7 +42,7 @@ module ::Hledger begin_date: begin_date, end_date: end_date, }, - runner: Hledger::Runner.new, + runner: runner, ) do on_success do |report:| Discourse.cache.write(cache_key, report, expires_in: CACHE_TTL) @@ -103,7 +104,7 @@ module ::Hledger :invalid end - def cache_key_for(first_post, report_type, begin_date, end_date) + def cache_key_for(runner, first_post, report_type, begin_date, end_date) [ "hledger", @topic.id, @@ -112,6 +113,7 @@ module ::Hledger begin_date, end_date, SiteSetting.hledger_path, + runner.version, ].join(":") end diff --git a/lib/hledger/runner.rb b/lib/hledger/runner.rb index a776641..1a78ee0 100644 --- a/lib/hledger/runner.rb +++ b/lib/hledger/runner.rb @@ -41,7 +41,7 @@ module Hledger def version return @version if defined?(@version) - @version = detect_version + @version = detect_version_cached end def execute(argv, stdin_data: nil) @@ -183,6 +183,20 @@ module Hledger result.stdout[/\d+\.\d+(?:\.\d+)?/] end + # The version is part of the report cache key, so remember it to avoid a + # `--version` subprocess on every request. + def detect_version_cached + return detect_version if @path.blank? + + key = "hledger:version:#{@path}" + cached = Discourse.cache.read(key) + return cached if cached + + detected = detect_version + Discourse.cache.write(key, detected, expires_in: 10.minutes) if detected + detected + end + def failure_result Result.new( success: false, diff --git a/spec/requests/hledger/reports_spec.rb b/spec/requests/hledger/reports_spec.rb index 268a603..06d8cec 100644 --- a/spec/requests/hledger/reports_spec.rb +++ b/spec/requests/hledger/reports_spec.rb @@ -129,6 +129,16 @@ RSpec.describe Hledger::ReportsController do expect(response.status).to eq(422) end + it "includes the hledger version in the cache key" do + get_report("accounts") + expect(response.parsed_body.dig("meta", "hledger_version")).to eq("1.52.1") + + allow(Hledger::Runner).to receive(:new).and_return(StubHledgerRunner.new(version: "1.53.0")) + + get_report("accounts") + expect(response.parsed_body.dig("meta", "hledger_version")).to eq("1.53.0") + end + it "rejects journals with include directives" do post.update!(raw: "```hledger\ninclude /etc/passwd\n```")