Resque is a background job processor for Ruby. Sometimes you need to do something that’ll take a long time and you don’t want that happening as part of the HTTP request lifecycle. It helps you do that.
But what happens when you want to do LOTS of things at once, you want to avoid the thundering herd problem by spreading that work out rather than doing it all at once.
Jitter is one way to do this, taking an example using Resque, say you want to recalculate something for products and you have 10,000 products. Here we can define a resque job to do the recalculation, taking in the product ID and then queue a job for each but we don’t want them to all start at the same time due to the load this would put on the DB. To fix that we add jitter, saying start these jobs somewhere between now and 120seconds time, picking a random duration per job.
To do this for Resque we can use resque-scheduler, which lets us queue work for the future, along with before_enqueue resque hook to let a job declare its jitter with, for example, @jitter_milliseconds = 10 on the job class.
Here is an example of this all wired up (note: We ended up using a slightly different code for the prod implementation due to requirements on our side, be sure to test the below works for you before adopting).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In my normal day I work in my local machine, in codespaces and in devcontainers.
Recently I started using Atuin which is an awesome tool for syncing your command history. Go check it out, it’s really nice!
A really cool feature is you can search history in different categories, like commands on this host or commands in this directory. Here I set this up for Codespaces so the host is the name of the repository. This means my commands from any instance of that repo’s Codespace are sync and searchable when in another new or existing Codespace.
Atuin has a public sync server but I prefer to sync to a local instance I host. This means I need a bit of wiring up to make this work when in a codespace or devcontainer.
Open Kitty and SSH to the Codespace with gh cli, to have a terminal window connected to the Codespace
With this flow I need a way to allow calls from within the Codespaces to connect to the Atuin server I’m running on my local network.
To do this I’m going to use SSH Reverse Port Forwarding, you’ve all probably forwarded a port from your local machine to a remote machine before but did you know it supports the other way around too? You can forward a port from the remote machine to a destination the local machine has access too.
The other bit to tackle is authentication from the Atuin instance in the Codespace to the local server. To get this wired up I’m using SCP to copy the session and key files up to the Codespace.
Then I can use the templating features in Chezmoi to customize my Atuin and zshrc files when running in a Codespace. The ATUIN_HOST_NAME env lets you override the host name the commands are tracked against. In my case I set this to codespace/$GITHUB_REPOSITORY so I can search commands by repo (neat feature of Atuin is you can view command history by host, cwd and more).
I want a nice way to launch this all, this should display a menu which lets me select a Codespace and have all of this done automatically from there. For me I’m using Rofi which is a nice launcher for linux but fzf or another would work fine here too.
As a bonus I also use LanguageTool spell/grammer checking service, again self hosting. This, via VSCode extension, gives me spell checking for my Markdown files. I can forward the ports for this in the same way as I did for Atuin.
Lastly, adding in a key binding fori3and I can now WIN+P and select my codespace then get all the bits I want open with language tools and atuin hooked up. When I move to a new codespace I get to keep my command history 🎉
Putting this all together you get (files trimmed to only the relevant bits).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters