Mike Perham :sidekiq:'s Avatar

Mike Perham :sidekiq:

@getajobmike.ruby.social.ap.brid.gy

Rubyist, guy behind @sidekiq and Faktory. For support, please open a new discussion at https://github.com/sidekiq/sidekiq/discussions. Personal: @getalifemike [bridged from https://ruby.social/@getajobmike on the fediverse by https://fed.brid.gy/ ]

666
Followers
0
Following
305
Posts
21.10.2024
Joined
Posts Following

Latest posts by Mike Perham :sidekiq: @getajobmike.ruby.social.ap.brid.gy

Sidekiq in the terminal My favorite tech movement in 2025 wasn’t anything artifical, but rather the resurgence in interest around building terminal interfaces with two new frameworks, Charm and Ratatui, which make developing pure text user interfaces easier than ever before using Go or Rust. They provide a huge set of components and examples showing you how to build various types of functionality. Mainframe applications ruled the 70s and 80s, providing terminal interfaces for business operations. You might still see a ticket agent using a terminal to check you in at the airport. That’s an interface to a mainframe application, allowing the agent to lookup your ticket and assign you a seat quickly, with just a few keystrokes. To this day I remember my mom, a pharmacist, complaining about the new DOS -> Windows upgrade that the IT department rolled out to stores. Navigating their retail point of sale terminal application was much faster with a keyboard, the Windows version required a stream of precise mouse clicks and couldn’t rely on typing by muscle memory. Today interactive terminal interfaces are rare but I think Charm and Ratatui make this option much easier to provide.

Introducing `kiq`, Sidekiq's new terminal interface, making your occasional admin operations even faster. Give it a try and let me know how to make this an amazing tool for you.

https://www.mikeperham.com/2026/03/10/sidekiq-in-the-terminal/

10.03.2026 23:24 👍 13 🔁 5 💬 1 📌 0

@psdavey I'm not a cook at all. I throw it in almost anything with rice, especially burritos and fried rice.

09.03.2026 22:10 👍 0 🔁 0 💬 0 📌 0

Sidekiq's TUI is getting a lot closer to usable now. What should the actual binary be called? `skq` maybe? `skui`?

09.03.2026 20:39 👍 0 🔁 0 💬 3 📌 0

Anyone know how Ruby terminal apps can determine the user's choice for language strings? My macOS terminal has "LANG=en_US.UTF-8", should TUIs parse that directly?

09.03.2026 19:06 👍 0 🔁 1 💬 0 📌 0
Post image

Really interesting post with details about the downfall of Huy Fong/Sriracha in 2015/16. Their Sambal is still a personal favorite.

https://old.reddit.com/r/KitchenConfidential/comments/1ro61g2/how_the_sriracha_guys_screwed_over_their_supplier/

09.03.2026 15:28 👍 1 🔁 0 💬 1 📌 0

@thisismissem not in Redis with a standard command that I’m aware of.

06.03.2026 01:09 👍 0 🔁 0 💬 1 📌 0

This saves me from having to do racy read-then-write logic like:

if val == 0
val = 1
else
val = 0
end

to flip the boolean.

05.03.2026 23:37 👍 4 🔁 0 💬 0 📌 0
INCR Increments the integer value of a key by one. Uses 0 as initial value if the key doesn't exist.

Wanted a Boolean that could be toggled atomically in Redis without Lua/XA and realized I could use INCR and check the value with modulo 2 where odd values (1,3,5,etc) representing true and the default is 0 or false, which gracefully works with nil in Ruby. https://redis.io/docs/latest/commands/incr/

05.03.2026 23:34 👍 0 🔁 0 💬 2 📌 0

I'm disappointed with Apple's new "super core" branding for the M5. "performance core" vs "efficiency core" is good, simple naming: gives you an immediate understanding for the difference between the two core types.

But "super core"? That's a meaningless buzzword that tells me nothing.

03.03.2026 22:09 👍 2 🔁 0 💬 0 📌 0

I've never believed the conventional wisdom that you need 100% uptime. For almost all services, users can handle small bits of downtime for DB migrations and other "hard" changes.

But that means 99.9% uptime, not 50% uptime.

03.03.2026 19:45 👍 2 🔁 0 💬 0 📌 0

I'm getting github failures like 50% of the time now, Actions failing, pushes failing. GitHub engineering appears to be on a path to technical incompetence and irrelevance.

What the hell is going on over there?

03.03.2026 19:30 👍 1 🔁 1 💬 6 📌 0
Original post on mastodon.social

We're looking for two Backend Ruby on Rails Web Developers to work with us remotely as part of the core team.

Ideally you are:

1. Very experienced with Ruby on Rails
2. Proficient in PostgreSQL, and familiar with Redis and Elasticsearch
3. Experienced in developing maintainable and scalable […]

20.02.2026 16:37 👍 9 🔁 155 💬 4 📌 2
The Vinyl Cache Project — Varnish HTTP Cache

TIL the Varnish Cache OSS project has renamed itself Vinyl Cache due to legal name sharing conflicts with the Varnish Cache business. Fun!

https://vinyl-cache.org

17.02.2026 20:59 👍 2 🔁 1 💬 0 📌 0

Is there a standard CSS beautifier/formatter tool? I want to diff the CSS rules for a few different pages and need a standard format to make the diff usable.

17.02.2026 20:15 👍 2 🔁 0 💬 2 📌 0

Sidekiq 8.1.1 is now available with a few minor fixes and a major deprecation.

https://github.com/sidekiq/sidekiq/blob/main/Changes.md#811

17.02.2026 18:38 👍 1 🔁 0 💬 0 📌 0
Original post on ruby.social

RE: https://ruby.social/@gsgermanok/116057765917733559

Good blog. They don't say which version of Sidekiq they are using but Sidekiq should not reserve an extra connection. Since 7.0, Sidekiq uses an internal pool for itself but it could be an app or 3rd party library bug too. Open an issue and […]

12.02.2026 15:14 👍 2 🔁 1 💬 0 📌 0

Periodic notice to business owners: you have the freedom to choose who you do business with. I just sent a 30 day account termination notice to a well-known supplier of arms and equipment to ICE and DHS. Resistance is patriotic. 🇺🇸

10.02.2026 21:55 👍 23 🔁 1 💬 0 📌 0
Original post on tldr.nettime.org

RE: https://mastodon.social/@Tutanota/116045913018556966

I understand where they are coming from but that is way too much of a technological framing. Even an encrypted open source Internet can be super unsafe to exist in.

Safety comes from social and political structures and decisions that […]

10.02.2026 12:57 👍 2 🔁 16 💬 2 📌 0

String("foo") => "foo"
Integer("123") => 123
Array("foo") => ["foo"]
Symbol("foo") => NoMethodError

Seems like an oversight?

09.02.2026 19:51 👍 5 🔁 0 💬 1 📌 0

My working theory is that Zendesk was purchased by private equity a few years ago and now they have no competent devops staff to fix this spam email deluge that’s been going on for days now.

08.02.2026 03:01 👍 4 🔁 1 💬 1 📌 0

@christine big layoffs in engineering and no new high touch customers requiring support. No new features and no support means low personnel and high profits. AI is their focus.

06.02.2026 21:33 👍 0 🔁 0 💬 0 📌 0
Preview
Zendesk tickets hijacked in massive spam campaign Someone is sending hundreds of pointless emails to people, using Zendesk's ticketing system.

I guess I could take 30 seconds to search… https://tech.yahoo.com/cybersecurity/articles/zendesk-tickets-hijacked-massive-spam-145000950.html

05.02.2026 18:59 👍 0 🔁 1 💬 0 📌 0

Did Zendesk have a compromise? I’ve gotten a dozen “new account” spam emails from various Zendesk installs over the last day.

05.02.2026 18:58 👍 0 🔁 0 💬 1 📌 0
Preview
announcing the 2026 Gem Fellowship Last month I announced my latest venture to support the Ruby open source community: the Gem Fellowship. I want this grant program to support and fund existing Ruby-related open source project maintainers and their ongoing efforts: fixing bugs and adding features for those libraries we know and love.

Announcing: the winners of the 2026 Gem Fellowship https://gem.coop/updates/2026-fellowship/ #ruby #oss

02.02.2026 19:16 👍 11 🔁 10 💬 1 📌 0
Defeating a 40-year-old copy protection dongle That’s right — this little device is what stood between me and the ability to run an _even older_ piece of software that I recently unearthed during an expedition of software archaeology. For a bit more background, I was recently involved in helping a friend’s accounting firm to move away from using an _extremely_ legacy software package that they had locked themselves into using for the last four decades. This software was built using a programming language called RPG (“Report Program Generator”), which is older than COBOL (!), and was used with IBM’s midrange computers such as the System/3, System/32, and all the way up to the AS/400. Apparently, RPG was subsequently ported to MS-DOS, so that the same software tools built with RPG could run on personal computers, which is how we ended up here. This accounting firm was actually using a Windows 98 computer (yep, in 2026), and running the RPG software inside a DOS console window. And it turned out that, in order to run this software, it requires a special hardware copy-protection dongle to be attached to the computer’s parallel port! This was a relatively common practice in those days, particularly with “enterprise” software vendors who wanted to protect their very important™ software from unauthorized use. Sadly, most of the text and markings on the dongle’s label has been worn or scratched off, but we can make out several clues: * The words “Stamford, CT”, and what’s very likely the logo of a company called “Software Security Inc”. The only evidence for the existence of this company is this record of them exhibiting their wares at SIGGRAPH conferences in the early 1990s, as well as several patents issued to them, relating to software protection. * A word that seems to say “RUNTIME”, which will become clear in a bit. My first course of action was to take a disk image of the Windows 98 PC that was running this software, and get it running in an emulator, so that we could see what the software actually does, and perhaps export the data from this software into a more modern format, to be used with modern accounting tools. But of course all of this requires the hardware dongle; none of the accounting tools seem to work without it plugged in. Before doing anything, I looked through the disk image for any additional interesting clues, and found plenty of fascinating (and archaeologically significant?) stuff: * We’ve got a compiler for the RPG II language (excellent!), made by a company called Software West Inc. * Even better, there are _two versions_ of the RPG II compiler, released on various dates in the 1990s by Software West. * We’ve got the complete source code of the accounting software, written in RPG. It looks like the full accounting package consists of numerous RPG modules, with a gnarly combination of DOS batch files for orchestrating them, all set up as a “menu” system for the user to navigate using number combinations. Clearly the author of this accounting system was originally an IBM mainframe programmer, and insisted on bringing those skills over to DOS, with mixed results. I began by playing around with the RPG compiler in isolation, and I learned very quickly that it’s the RPG compiler itself that requires the hardware dongle, and then the compiler automatically injects the same copy-protection logic into any executables it generates. This explains the text that seems to say “RUNTIME” on the dongle. The compiler consists of a few executable files, notably `RPGC.EXE`, which is the compiler, and `SEU.EXE`, which is a source editor (“Source Entry Utility”). Here’s what we get when we launch SEU without the dongle, after a couple of seconds: A bit rude, but this gives us an important clue: this program must be trying to communicate over the parallel port over the course of a few seconds (which could give us an opportunity to pause it for debugging, and see what it’s doing during that time), and then exits with a message (which we can now find in a disassembly of the program, and trace how it gets there). A great tool for disassembling executables of this vintage is Reko. It understands 16-bit real mode executables, and even attempts to decompile them into readable C code that corresponds to the disassembly. And so, looking at the decompiled/disassembled code in Reko, I expected to find `in` and `out` instructions, which would be the telltale sign of the program trying to communicate with the parallel port through the PC’s I/O ports. However… I didn’t see an `in` or `out` instruction anywhere! But then I noticed something: Reko disassembled the executable into two “segments”: `0800` and `0809`, and I was only looking at segment `0809`. If we look at segment `0800`, we see the smoking gun: `in` and `out` instructions, meaning that the copy-protection routine is definitely here, and best of all, the entire code segment is a mere 0x90 bytes, which suggests that the entire routine should be pretty easy to unravel and understand. For some reason, Reko was not able to decompile this code into a C representation, but it still produced a disassembly, which will work just fine for our purposes. Maybe this was a primitive form of obfuscation from those early days, which is now confusing Reko and preventing it from associating this chunk of code with the rest of the program… who knows. Here is a GitHub Gist with the disassembly of this code, along with my annotations and notes. My x86 assembly knowledge is a little rusty, but here is the gist of what this code does: * It’s definitely a single self-contained routine, intended to be called using a “far” `CALL` instruction, since it returns with a `RETF` instruction. * It begins by detecting the address of the parallel port, by reading the BIOS data area. If the computer has more than one parallel port, the dongle must be connected to the _first_ parallel port (LPT1). * It performs a loop where it writes values to the data register of the parallel port, and then reads the status register, and accumulates responses in the `BH` and `BL` registers. * At the end of the routine, the “result” of the whole procedure is stored in the `BX` register (`BH` and `BL` together), which will presumably be “verified” by the caller of the routine. * Very importantly, there doesn’t seem to be any “input” into this routine. It doesn’t pop anything from the stack, nor does it care about any register values passed into it. Which can only mean that the result of this routine is _completely constant_! No matter what complicated back-and-forth it does with the dongle, the result of this routine should always be the same. With the knowledge that this routine must exit with some magic value stored in `BX`, we can now patch the first few bytes of the routine to do just that! Not yet knowing which value to put in `BX`, let’s start with 1234: BB 34 12 MOV BX, 1234h CB RETF Only the first four bytes need patching — set `BX` to our desired value, and get out of there. Running the patched executable with these new bytes still fails (expectedly) with the same message of “No dongle, no edit”, but it fails immediately, instead of after several seconds of talking to the parallel port. Progress! Stepping through the disassembly more closely, we get another major clue: The only value that `BH` can be at the end of the routine is 76h. So, our total value for the magic number in `BX` must be of the form 76xx. In other words, only the `BL` value remains unknown: BB __ 76 MOV BX, 76__h CB RETF Since `BL` is an 8-bit register, it can only have 256 possible values. And what do we do when we have 256 combinations to try? Brute force it! I whipped up a script that plugs a value into that particular byte (from 0 to 255) and programmatically launches the executable in DosBox, and observes the output. Lo and behold, it worked! The brute forcing didn’t take long at all, because the correct number turned out to be… _6_. Meaning that the total magic number in `BX` should be 7606h: BB 06 76 MOV BX, 7606h CB RETF Bingo! And then, proceeding to examine the other executable files in the compiler suite, the parallel port routine turns out to be _exactly the same_. All of the executables have the exact same copy protection logic, as if it was rubber-stamped onto them. In fact, when the compiler (`RPGC.EXE`) compiles some RPG source code, it seems to copy the parallel port routine from itself into the compiled program. That’s right: the patched version of the compiler will produce executables with the same patched copy protection routine! Very convenient. I must say, this copy protection mechanism seems a bit… simplistic? A hardware dongle that just passes back a constant number? Defeatable with a four-byte patch? Is this really worthy of a patent? But who am I to pass judgment. It’s possible that I haven’t fully understood the logic, and the copy protection will somehow re-surface in another way. It’s also possible that the creators of the RPG compiler (Software West, Inc) didn’t take proper advantage of the hardware dongle, and used it in a way that is so easily bypassed. In any case, Software West’s RPG II compiler is now free from the constraint of the parallel port dongle! And at some point soon, I’ll work on purging any PII from the compiler directories, and make this compiler available as an artifact of computing history. It doesn’t seem to be available anywhere else on the web. If anyone reading this was associated with Software West Inc, feel free to get in touch — I have many questions! Share: TwitterFacebookPin ItWhatsAppLinkedInBuffer

Defeating 40 yr old copy protection dongle https://dmitrybrant.com/2026/02/01/defeating-a-40-year-old-copy-protection-dongle

02.02.2026 06:40 👍 4 🔁 2 💬 2 📌 0

@kerrick The r_r gem is ballooning in size, currently 18MB. You'll want to be a little more deliberate about the files you include. As an example, sidekiq is <300KB.

28.01.2026 22:21 👍 0 🔁 0 💬 0 📌 0
Original post on bark.lgbt

I'm #colorblind and I use https://xkcd.com/color/rgb/ frequently.

Randall 'xkcd' Monroe did a survey of over 100,000 readers where he showed them random rgb colors and said "what would you call this?" and afterwards he did his best to sort the results into the most popular color names and the […]

27.01.2026 16:53 👍 34 🔁 156 💬 9 📌 0
Adding Mastodon Comments I’m enabling comments via Mastodon using this webcomponent. @dpecos has done a nice job keeping it self-contained and has made good tradeoffs in functionality vs simplicity IMO. Thanks @sardaukar!

@sardaukar We're live, enjoy your new fame as my first commenter! https://www.mikeperham.com/2026/01/27/adding-mastodon-comments/

28.01.2026 00:56 👍 0 🔁 2 💬 0 📌 0
Adding Mastodon Comments I’m enabling comments via Mastodon using this webcomponent. @dpecos has done a nice job keeping it self-contained and has made good tradeoffs in functionality vs simplicity IMO. Thanks @sardaukar!

@sardaukar We're live, enjoy your new fame as my first commenter! https://www.mikeperham.com/2026/01/27/adding-mastodon-comments/

28.01.2026 00:56 👍 0 🔁 2 💬 0 📌 0