All Around the Mond
Last week there was no Skill Issue. Between work and the hunt for a home, there wasn't time. The good news is that we've got an accepted offer on a place to live! We'll be getting the keys and moving in shortly before we head to Japan for RubyKaigi!
If you can't tell from the exclamation points in the above paragraph, I'm excited. We've been living in a beautiful condo for the past couple of years, but for various reasons I won't get into here, it really hasn't felt like our home. Also my desk is in the living room.
I can't wait to not just have a place of our own, but I'll have an office with it's own bathroom that's completely separate from the main living space. That separation of work from the rest of your life is important to me.
I've finally more-or-less switched to my own cross-posting tool, Mond1. It's my first non-trivial Go project and so far, Go has been great. The impetus for this project was twofold:
- The cross-posting tool I was using doesn't properly support GoToSocial, the Mastodon-compatible Fediverse platform I use. (This is me.)
- None of the tools I looked at supported the exact flow I wanted.
I wanted to be able to queue my posts into "channels", and have the tool (on a set schedule) post the oldest post from the (non-empty) channel that I least recently posted from.
Basically, I wanted to be able to stick a bunch of posts in the Ruby bucket, the Solidus bucket, the general programming bucket, et cetera, and have the system rotate through posting from each one. That way I can draft a ton of posts on varying topics and trust that the system will handle posting them at a reasonable rate and with reasonable variety. If I suddenly have a lot to say on one topic today, I can queue it up and the system will avoid spamming it all out at once without any extra effort from me.
That's done. "Mond", as it's called, has support for:
- Bluesky and Mastodon (and anything Mastodon-compatible)
- an arbitrary number of accounts
- threads of arbitrary length
- images with alt text
- an arbitrary number of channels that can be managed via the web interface
- immediate posting
- draft (i.e. unqueued) posts
I have dreams for more complex social-media management features down the road, but this was enough to get me off the other tool I was using.
The frontend uses Vite. The interaction is almost entirely HTMX, but the "compose" interface is React. It doesn't need to be React, but it was the easiest way for me to get the more complex interactions I wanted. I might port it back to HTMX later.
The database is just Postgres, with a pretty simple schema. There's not caching or anything in the app, so the deployment is just a Postgres instance and a single web instance. The web instance handles the scheduled posts in the "background".
It was a little weird coming from the Rails ecosystem where I'd have normally reached for ActiveJob and all that to handle the background posting. Instead, there's just a little background ticker that checks if we've hit one of the scheduled times to post periodically. Simple.
The application is very lean, only using about 75MiB of memory. I'm running it on a shared CPU 1x on Fly.io and my P50 is 46ms and my P95 is 298ms. Keep in mind that it's connecting to a similarly low-resource database, so very reasonable given the provisioning. (This application could totally use SQLite if I wanted and it would be much faster.)
I'm left with one question: should I have just built this with Ruby/Rails? In that this was mostly an exercise in figuring out what building web applications was like, this was a success. It's a web application. I built it. I could do this again. I have some idea of what the Go ecosystem is like.
Now, I have to maintain it, though. I'll tell you what. It's not unlikely this thing gets rewritten in a weekend in Ruby one day. For now, though, it's serving its purpose. I guess it's now an experiment in what it's like to maintain web applications written in Go.
You know what's great? Noodly, proggy, death metal. If you also think noodly, proggy, death metal is great, then go listen to Cryptic Shift's new record, Overspace & Supertime. You will not be disappointed.
Overspace & Supertime | Cryptic Shift
5 track album
-
"Mond" is the second syllable of my first name. ↩