whoami
Lucas Jenß
cat /etc/motd
The Coding Journal ツ — Notes taken on an epic coding journey. Technical solutions, debugging notes, and practical guides from the trenches of software development.
ls -la ~/languages/
- drwxr-xr-x
- ▶ PHP
- ▶ Ruby
- ▶ Scala
- ▶ C#
- ▶ JavaScript
- ▶ Objective-C
- ▶ Shell Scripting
ls -la ~/toolchain/
- drwxr-xr-x
- ▶ Typo3
- ▶ Akka
- ▶ Capistrano
- ▶ Git
- ▶ MAMP
- ▶ Adobe Illustrator
- ▶ NSTrackingArea (Cocoa)
uname -a
- drwxr-xr-x
- ▶ Mac OS X
- ▶ Unix
Warm the Application Cache After a Capistrano Deploy
A Capistrano after-deploy hook can run a cache-warming command as part of a release, removing the need for an engineer to visit production and rebuild expensive data manually. A useful hook runs after the new release has been published and linked as current, but before the deployment is declared healthy.
The hook should orchestrate, not contain, the business logic. Give the application a tested command that prepares its data, then let Capistrano invoke that command with the correct environment and release. This keeps the warmer usable from a workstation, a CI pipeline, or an Australian support team working outside the deployment server.
Build the cache warmer in the application
Give the application one command that prepares every cache entry required immediately after a release. A Rails application might expose bin/rails cache:warm; a PHP application could provide an equivalent Artisan or console command. The important contract is consistent output, predictable completion, and a non-zero exit status when the cache is not safe.
# lib/tasks/cache.rake
namespace :cache do
desc "Prepare cached catalogue data"
task warm: :environment do
CatalogueWarmer.new.call
end
end
Adapt the task to the project rather than copying the example literally. It may rebuild navigation, product facets, pricing summaries, or search suggestions. Prefer deterministic keys and stable ordering so two runs produce the same result.
The warmer should be idempotent because Capistrano can retry a failed release. It should also be bounded by a timeout, write progress to the application log, and report how many entries were created. Build replacement values before removing old ones so a failed run does not leave production with an empty cache.
Wire the warmer into Capistrano
Keep the deployment-specific code in config/deploy.rb, while the warming logic remains in the application repository. A typical Capistrano 3 task looks like this:
set :rails_env, -> { fetch(:stage) }
namespace :app do
desc "Warm the application cache"
task :warm_cache do
on roles(:app) do
within release_path do
with rails_env: fetch(:rails_env) do
execute :bundle, "exec", :rake, "cache:warm"
end
end
end
end
end
after "deploy:published" do
invoke! "app:warm_cache"
end
The after hook runs with release_path pointing at the newly published release. invoke! deliberately treats a failed warming command as a deployment failure, which is appropriate when application requests would otherwise overload the database or serve incorrect data.
roles(:app) normally runs the command on every application host. That is useful when each host has a local cache, but it can duplicate work when the target is one shared Redis or Memcached service. Assign one host to a dedicated warming role if the task is safe only once. For broader release sequencing, Mike Meredith's deployment workflow notes offer a useful reference.
Keep warmed data available across releases
A local cache under the release directory can disappear as soon as the next deployment creates a new release. If the application expects the warmed files to survive, link that directory into shared. For example:
set :linked_dirs, %w[log tmp/pids tmp/cache]
This gives the current release a stable path to tmp/cache, while Capistrano still supplies application code from the release directory. Check that the deploy user can write to the shared path and that stale files are removed deliberately when their schema or key format changes.
External caches need different safeguards. A Redis-backed catalogue might use namespaced keys such as catalogue:v12, while a Memcached deployment can rely on expiring entries. The warming task should write complete values, use atomic replacement where possible, and avoid deleting keys that another release still needs.
The hook also depends on production services being reachable. Database credentials, encryption keys, Redis authentication, and the correct RAILS_ENV must be available to the deploy user without printing secrets into command output. Test the task with the same runtime and configuration paths used by the application process.
Fail visibly without creating a rollback trap
A strict hook creates an operational decision. If warming is critical, let invoke! stop the release and alert the deployer. If the cache is only an optimisation, replacing invoke! with invoke may be safer than marking a healthy release as failed, provided monitoring raises an alert and the application can fall back to uncached reads.
Do not assume an automatic rollback will repair the cache. The new code may already be serving traffic, and cached values written by that code may no longer match the previous release. Decide whether rollback is appropriate for the application, then clear or rebuild the relevant namespace separately if the release is reversed.
Record the start time, finish time, entry count, and exit status for every warm-up. A small synthetic request can then check a known cache-backed page during the release. I also keep the author's TYPO3 upgrade troubleshooting notes nearby because upgrade failures need reproducible symptoms, not a hopeful cache clear that hides the real fault.
Fit the release into Australian operations
Australian release windows have their own practical details. Teams in Sydney, Melbourne, and Brisbane may agree on a mid-morning deployment, but Melbourne follows Sydney while Brisbane remains on AEST and does not change for daylight saving. Check the current AEST or AEDT offset before a release and avoid scheduling around the daylight-saving transition.
The cached data should reflect the Australian market as customers see it. For an .com.au shop, that may mean GST-inclusive prices, Australian dollar shipping estimates, postcode rules, and stock shown in local stores. Warming against an overseas locale can leave valid-looking prices or delivery promises in place until the first cache miss repairs them.
Use Australian spelling and dd/mm/yyyy dates in logs and test fixtures, and make sure a cache key changes when either changes. These details are easy to overlook in a global sample dataset. A release check performed from Sydney, Melbourne, and Brisbane also gives quick evidence that remote application servers can reach shared cache and database services.
Verify the release and keep the evidence
Run the warming task against staging data that resembles production, including large catalogues and the slowest supported database path. Capture its normal duration, memory use, and entry count. Those figures become a baseline, so an unusual slowdown in production is visible rather than hidden inside a successful SSH command.
Compare release timings before choosing the final policy:
| Strategy | Behaviour during release | Main risk | Suitable when |
|---|---|---|---|
| Clear after publish | Deletes old values and rebuilds on demand | Cold reads and extra database load | Values are cheap to recreate |
| Warm after publish | Builds replacement values while the new release is live | A brief mixed state | The task is fast and idempotent |
| Warm before publish | Builds values in the candidate release before traffic moves | A failure blocks the release | The release and cache models are compatible |
| Background refresh | Rebuilds values after traffic resumes | Stale values may persist briefly | The cache is not correctness-critical |
Make the hook observable in production, compare it with the baseline, and confirm that a cache-backed request returns the expected data before declaring the release healthy.
Add the application warming command to the repository, test it with representative staging data, and attach it to deploy:published only after both checks pass. Ship the tested hook with the next release and keep an owner ready to inspect cache metrics and deployment logs if the Australian release window needs to pause.
cat ~/interests.json
| Key | Value |
|---|---|
| editor | Terminal-first workflow |
| os | Mac OS X / Unix |
| vcs | Git, distributed version control |
| deploy | Capistrano, cron automation |
| graphics | SVG, Adobe Illustrator troubleshooting |
| networking | IP validation, SSH, VPN |
git log --oneline --reverse
Solving SVG import issues in Adobe Illustrator CS6 and CC
When importing an SVG into Illustrator, the operation fails with an unknown error [CANT]. A workaround for this Adobe-side bug.
Solving NDK build issues on OS X
Troubleshooting native development kit compilation problems on Mac OS X.
Programmatically adding PHP generated TypoScript to the backend configuration
Integrating dynamically generated TypoScript into Typo3 backend setups using PHP.
ArgumentError: Could not parse PKey: no start line
Debugging an SSH key parsing error encountered during deployment.
Validating IP-Addresses in PHP
Using PHP filter functions with flags like FILTER_FLAG_IPV4 and FILTER_FLAG_IPV6, and understanding how filter_var handles reserved IP addresses.
Cocoa: Using NSTrackingArea
A short tutorial on using Cocoa's NSTrackingArea to capture mouseEntered and mouseExited events.
cat ~/contact.txt