←back to thread

90 points superstarryeyes | 1 comments | | HN request time: 0.204s | source

Well, I certainly tried. I had to, because it has a certain quirk inspired by "digital minimalism."

The quirk is that it only allows you to fetch new articles once per day (or X days).

Why? Let me explain...

I want my internet content to be like a boring newspaper. You get it in the morning, and you read the whole thing while sipping your morning coffee, and then you're done! No more new information for today. No pings, no alerts, peace, quiet, zen, etc.

But with that, I needed it to be able to fetch all articles from my hundreds of feeds in one sitting. This is where Zig and curl optimisations come in. I tried to do all the tricks in the book. If I missed something, let me know!

First off, I'm using curl multi for the network layer. The cool thing is it automatically does HTTP/2 multiplexing, which means if your feeds are hosted on the same CDN it reuses the same connection. I've got it configured to handle 50 connections total with up to 6 per host, which seems to be the sweet spot before servers start getting suspicious. Also, conditional GETs. If a feed hasn't changed since last time, the server just says "Not Modified" and we bail immediately.

While curl is downloading feeds, I wouldn't want CPU just being idle so the moment curl finishes downloading a single feed, it fires a callback that immediately throws the XML into a worker thread pool for parsing. The main thread keeps managing all the network stuff while worker threads are chewing through XML in parallel. Zig's memory model is perfect for this. Each feed gets its own ArenaAllocator, which is basically a playground where you can allocate strings during parsing, then when we're done, we just nuke the entire arena in one go.

For parsing itself, I'm using libexpat because it doesn't load the entire XML into memory like a DOM parser would. This matters because some podcast feeds especially are like 10MB+ of XML. So with smart truncation we download the first few X mb's (configurable), scan backwards to find the last complete item tag, cut it there, and parse just that. Keeps memory usage sane even when feed sizes get massive.

And for the UI I just pipe everything to the system's "less" command. You get vim navigation, searching, and paging for free. Plus I'm using OSC 8 hyperlinks, so you can actually click links to open them on your browser. Zero TUI framework needed. I've also included OPML import/export and feed groups as additional features.

The result: content from hundreds of RSS feeds retrieved in matter of seconds, and peace of mind for the rest of the day.

The code is open source and MIT licensed. If you have ideas on how to make it even faster or better, comment below. Feature requests and other suggestions are also welcome, here or GitHub.

Show context
A1aM0 ◴[] No.46308487[source]
The 'once a day' fetching limitation is a fascinating idea. It really captures the vibe of reading a physical newspaper in the morning rather than constantly checking for updates. I think many of us could use a tool that enforces a bit of 'digital silence' like this.
replies(4): >>46308837 #>>46310419 #>>46310509 #>>46316622 #
mocheeze ◴[] No.46308837[source]
In middle school (age 11-13 in the late '90s, USA) I had a hand-me-down Palm Pilot (probably upgraded to Handspring in there). I'd leave it on my serial(?) port cradle and have it download my daily news from sites like IGN and Slashdot over 56K before I woke up. I was also the kid that regularly read the "Time Life for Kids" mags they'd pass out to us in homeroom. That's the outlet I learned about Napster from and hooked my school onto. Your comment reminded me of those days. Now I'm still desperately hooked on RSS since the early days.

ETA: When I was a late teen I ended up managing a bunch of younger teams for a free mod for an indie PC game called Blockland. I had them code up IRC and RSS capabilities into the mod from scratch in the Torque Game Engine's custom TorcueScript. I couldn't believe what those kids were capable of. They all went into programming, engineering, or founding their own companies out of highschool and college. If one of them told me something was impossible I'd just tell them that I saw that a competing mod already figured it out. Magically my dudes had a solution really quick lol. Sometimes when you have limited resources and/or experience the old and proven ways are just as good.

Was great when they had all that XML experience in a weird scripting language and I asked them to implement Jabber in-game from my Dreamhost shared-hosting plan. Crazy what a bunch of teens can do for an online Lego-like game.

Thanks for letting this older dude wax nostalgic off the rails. Hope it reminds others on HN about early hacking days like OP's project.

replies(1): >>46309377 #
1. A1aM0 ◴[] No.46309377[source]
Love it. It’s funny how we are now building modern tools just to try and get back that simple 'Palm Pilot morning read' vibe.