Emacs, The Leetcode Archive Webserver

There's been a gap in publishing posts after my post on setting up a PHP environment in emacs. It's because I've been working on https://leetcode-archive.onrender.com/. I've been making room for the past 2 months on this project consistently with some breaks between. Honestly I never thought I'd get to the point where you'd be reading about this. It's weird any angle you look at it.

lc-archive-screenshot.png
Figure 1: a screenshot of the front page of lc-archive with some query parameters

Here's what's weird about it:

  • Requests are served via emacs.
    • The server backend reads your request in emacs lisp.
    • HTML is generated through emacs lisp. I don't even have html templates that aren't lisp.
    • Yes, records are backed by a non-lisp database, but interfacing with the database is done in emacs lisp.
  • Did I mention it's emacs? Inside a docker container??? Oooohh…!
    • And I did that because I have no money for an AWS EC2?
    • And that I could not find any where to host an emacs app? Because…in the web there are approx. 0 emacs apps, so why would a cloud platform think that someone would ship an emacs app and have that as part of their product offering?
    • And that only a few cloud providers allow shipping a docker container for free, but with resource restrictions?1
    • And I cannot afford a hosted db? Or that a free hosted db would have no usable data retention?
    • And that my container starts cold, and thus I have data loss issues every time the container starts?
    • And in this purgatory of suffering, I had to make sure the data auto backfills itself, and on every UTC midnight, I grab the new daily problem? Before data gets wiped clean again?
    • And that I did this with emacs timers and graphql requests from emacs?
    • And that you can get your name/alias in the project sponsors section if you'd like to fund the project?
  • It uses transparent, non-opaque cursors for paginating data. I spend as little time in the DB grabbing those records for you as I can2. This was overkill for scaling, but I feel like I have to tell every star in the sky and every ancient civilization that once inhabited them: "Hey, I implemented cursor pagination for (almost) arbitrary, user-defined sort keys and sort orders! It's way faster than using LIMIT + OFFSET."
  • It's self-exposing--it shows you the source code it's running: https://leetcode-archive.onrender.com/src/
  • It's the only resource online where you can query for dates when a specific problem was a daily problem. (Ok, fine, that is a bit niche usecase but you can query for a bunch of stuff).
  • Did I mention? Cursor based pagination?3 Yes I did. And I auto generate each SQL query using recursion to get the right sort order for the right sort keys, whether it's forward OR backward pagination?
  • And, maybe not so great, it's running HTTP 1.1. HTTP 2 was a massive upgrade over 1. Fund my work, and I'll do whatever I can to upgrade the elnode package to use HTTP 2 or higher.
  • And it's all public domain code. Go. Steal it. Make your own thing. Or make the project better.
  • And that it's a site that requires absolutely no javascript?
Upon the sky, it is
written,
that on this day,
4025-01-26,
cursor based pagination was implemented in the application server for
https://leetcode-archive.onrender.com/.

The stars will speak the names of my sponsors for eternity.

- jwow0

And if you like the work I do,

  • from reading my blog,
  • benefiting from the very niche software projects I write,
  • or enjoy my videos

sponsor more my work at https://www.patreon.com/patreon/jwow0 and have your name appear in the timeless credits in a project if your choice4. See you soon!


1

I guess I could have used replit, but I am not excited about nix anymore.

2

Though, I still need to add better DB indices so queries with different sort orders can benefit. (With enough money/time I can denormalize the data a bit more too, since a question may appear on different days).

3

Okay, probably not the coolest or hardest thing I've implemented, but it seemed complicated to begin with. Even slack's oft-referenced article about cursor based pagination does not talk about how to handle arbitrary sort keys and sort orders. Take a look: https://slack.engineering/evolving-api-pagination-at-slack/.

Bruno's article https://brunoscheufler.com/blog/2022-01-01-paginating-large-ordered-datasets-with-cursor-based-pagination made it clearer for me. I had to make the connection myself for more complicated cases when you have a mix of ASC and DESC on keys, + how you'd programatically generate the SQL query, which I did by parsing out the ORDER BY clause. The nested structure of handling the sort keys is fairly regular.

4

I'm still figuring out the details of sponsoring my work. Feel free to email me if this interests you.