commit a0a120b31e467d6741d94e1eb4a2e7603e31ce71
parent 7b769b3e1f47f17b902e7d87f12f7c78aef2e4f9
Author: David Eisinger <[email protected]>
Date: Wed, 8 Apr 2026 23:54:20 -0400
Cache dither results
Diffstat:
5 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml
@@ -9,6 +9,7 @@ on:
env:
HUGO_VERSION: 0.160.1
DEPLOY_DIR: /var/www/davideisinger.com
+ DITHER_CACHE_DIR: /workspace-cache/dither
jobs:
deploy:
diff --git a/.gitignore b/.gitignore
@@ -1,4 +1,5 @@
.hugo_build.lock
+.cache
public
resources/_gen
secret.key
diff --git a/bin/build b/bin/build
@@ -3,10 +3,13 @@ set -euo pipefail
repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
dither_dir="${repo_root}/bin/dither"
+cache_dir="${DITHER_CACHE_DIR:-${repo_root}/.cache/dither}"
+
+mkdir -p "${cache_dir}"
pushd "${dither_dir}" >/dev/null
bundle install
-ROOT="${repo_root}/content" KEY="${repo_root}/secret.key" bundle exec rackup -p 4567 &
+ROOT="${repo_root}/content" KEY="${repo_root}/secret.key" DITHER_CACHE_DIR="${cache_dir}" bundle exec rackup -p 4567 &
dither_pid=$!
popd >/dev/null
diff --git a/bin/dither/dither.rb b/bin/dither/dither.rb
@@ -1,5 +1,7 @@
require "sinatra"
require "mini_magick"
+require "digest"
+require "fileutils"
require "tempfile"
MiniMagick.logger.level = Logger::DEBUG
@@ -8,6 +10,26 @@ ROOT = ENV.fetch("ROOT")
KEY = ENV.fetch("KEY")
DITHER = ENV["DITHER"] != "0"
FORMAT = "png"
+CACHE_DIR = ENV["DITHER_CACHE_DIR"]
+
+def cache_path_for(path, geometry)
+ return unless CACHE_DIR
+
+ source_path = "#{ROOT}/#{path}.enc"
+ stat = File.stat(source_path)
+ cache_key = Digest::SHA256.hexdigest([
+ path,
+ stat.size,
+ stat.mtime.to_f,
+ geometry,
+ DITHER,
+ FORMAT,
+ 1
+ ].join("\0"))
+
+ FileUtils.mkdir_p(CACHE_DIR)
+ File.join(CACHE_DIR, "#{cache_key}.#{FORMAT}")
+end
get "/*" do |path|
halt 404, {"Content-Type" => "text/plain"}, "not found" unless File.exist?("#{ROOT}/#{path}.enc")
@@ -17,6 +39,11 @@ get "/*" do |path|
geometry = params["geo"] unless params["geo"] == ""
geometry.gsub!(/\d+/) { |n| n.to_i * 2 } if geometry && !DITHER
+ cached_path = cache_path_for(path, geometry)
+ if cached_path && File.exist?(cached_path)
+ return File.binread(cached_path)
+ end
+
decrypted = Tempfile.new(["dither", File.extname(path)])
decrypted.binmode
decrypted.close
@@ -59,7 +86,15 @@ get "/*" do |path|
end
convert << "#{FORMAT.upcase}:-"
- convert.call
+ output = convert.call
+
+ if cached_path
+ temp_cache_path = "#{cached_path}.tmp-#{Process.pid}"
+ File.binwrite(temp_cache_path, output)
+ FileUtils.mv(temp_cache_path, cached_path)
+ end
+
+ output
ensure
decrypted.unlink
end
diff --git a/bin/server b/bin/server
@@ -3,9 +3,12 @@ set -euo pipefail
repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
dither_dir="${repo_root}/bin/dither"
+cache_dir="${DITHER_CACHE_DIR:-${repo_root}/.cache/dither}"
+
+mkdir -p "${cache_dir}"
pushd "${dither_dir}" >/dev/null
-ROOT="${repo_root}/content" KEY="${repo_root}/secret.key" bundle exec ruby dither.rb &
+ROOT="${repo_root}/content" KEY="${repo_root}/secret.key" DITHER_CACHE_DIR="${cache_dir}" bundle exec ruby dither.rb &
dither_pid=$!
popd >/dev/null