• The REPL: Issue 121 - September 2024

    OAuth from First Principles

    The articles explains how the problem of sharing access between servers evolves into OAuth, as one starts trying to solve the security issues in the naive implementation.

    The “email is authentication” pattern

    For some people, logging into a website means using the “forgot your password” flow every time they want to log in. They do in lieu of other schemes like using the same password, using a password manager, using a password generation scheme, etc.

    Are people well informed about the options? From the website’s perspective it doesn’t matter much: Essentially, having access to an email address grants you access to the website. As long as that is the case, we might as well use “magic links” for authentication and do away with passwords all together.

    In fact, in many places, email is now also used as 2-factor authentication. If the website has a “forgot my password” flow via email, then 2-factor via email only adds the illusion of security.

    Solid Queue 1.0 released

    I’m happy about this development: Rails should definitely have a canonical queue implementation. I’m also interested in it’s performance because of the UPDATE FOR SKIP LOCKED usage. I plan on evaluating it in in the future vs GoodJob. I noticed a few things about the announcement:

    37 Signals production setup uses claims 20M jobs per day with 800 workers. That seems like a lot of workers, but without the context of what those workers are doing.

    They are using a separate database for the queue. While I get that it alleviates some of the performance concerns with the main database, you also loose transactionality between your jobs and the rest of your writes: To me, transactionality is one of the main selling points of using a db-based queueing system. I’ve chased many production issue where using a separate data store for the jobs ends up causing the queue workers to look for records that are not visible, either temporarily due to a race condition, or permanently because of a roll-back. Using 2 separate databases also means that each Rails process (web or worker) needs a connection to each database.

    In the announcement there is a link to a Postgres-only issue recently fixed, that made me realize that Solid Queue has concurrency controls built-in, and uses INSERT ON CONFLICT DO NOTHING to enforce them. That is clever, and more efficient than checking for existence of the concurrency key before inserting.

    Read on →

  • Using expect to tailor environment

    I recently learned to leverage expect. According to the man pages it is:

    expect - programmed dialogue with interactive programs

    I often need to ssh into remote hosts that both are ephemeral and I don’t have much control over. Any environment customization that I do is one-time only, because odds are that next time I connect, it will be to a different host. Yet, I’d like to be in a familiar environment. That is where expect comes in.

    expect provides a DSL of sorts to interactively use programs in the command line. I use it to front ssh and do a few common tasks every time I log in:

    #!/usr/bin/env expect
    # Front ssh and automate env settings once on remote machine
    
    set environment [lindex $argv 0];
    
    spawn ssh $environment
    expect "\$ " {
      send ". entry.sh"
    
      send -- "alias db_replica='psql ..."
      send -- "\n"
    
      send -- "export EDITOR=nano"
      send -- "\n"
    
      expect "\$ " { interact }
    }
    

    That script:

    1. Reads the first argument to it and sets to a local variable named “environment”.
    2. Starts an instance (spawn) of ssh, passing the value of environment to it.
    3. It then waits (expect) until it reads a $
    4. It sends a few commands to source a file, create an alias, export a variable, etc.
    5. It then expects another prompt and starts and switches to interactive mode (interact)

    That last steps is what “drops” me into the terminal in the remote host, personalized with my taste.

    This is just the proverbial tip of the iceberg. The expect manual has a lot more information.

    Read on →

  • The REPL: Issue 120 - August 2024

    Structure Your ERb and Partials for more Maintainable Front-end Code in Rails

    Interesting exploration of how to write better ERB views in Rails. One the one hand, adding ERB tags and interspersed Ruby code in HTML is not optimal. On the other extreme, is generating everything in Ruby with tag helpers, which is also less than optimal. No matter where you land, it seems that one needs to know both HTML, ERB and some Ruby DSL to write views, with an eye to what HTML will be generated.

    actual_db_schema: Wipe out inconsistent DB and schema.rb when switching branches

    Interesting library. It attempts to solve the issue of jumping between multiple branches in Rails code bases and the DB schema getting out of sync. I have not used it, and can’t say that I’ve struggled much with this problem. What I do struggle with is structure.sql conflicts of different branches all wanting to insert their migration number in the same spot.

    Read on →

  • The REPL: Issue 119 - July 2024

    Entering text in the terminal is complicated

    Most of the things that I associate with “usable” CLIs actually comes from readline. TIL that you can wrap anything with readline! rlwrap nc. It doesn’t seem to be installed on my Mac, by default though.

    PostgreSQL INSTEAD OF Triggers

    I’ve been working with Postgres triggers recently. They are immensely powerful, but I find the syntax hard to get used to, and the manual has limited examples. In particular this tutorial shows a use of RETURNING ... INTO to put a value into a variable that made it much easier to achieve what I wanted, instead of a chain of CTEs with INSERT INTO that was becoming unwieldy.

    Event sourcing for smooth brains: building a basic event-driven system in Rails

    I don’t consider what this article described to be event sourcing. It’s a light event system in Rails, which is great, but not exactly event sourcing.

    In event sourcing (as understood by most of the literature), the event records are the source of truth, and by “applying” those events you get the current state of the system. What they describe is not that. The system in the article has events and subscribers that act on those events, and the state of the system is maintained separately from the events.

    In trying to simplify, they threw out some of what the event sourcing typically consider the most useful parts. Basically, they kept a pub/sub system hooked into after_commit hooks. Useful, but not what is described on the tin.

    Read on →

  • The REPL: Issue 118 - June 2024

    Better Know A Ruby Thing: On The Use of Private Methods

    Noel Rappin writes thoughtfully about private methods. I actually approach writing classes in the opposite way that he does, and I also do it because of past experience. I currently work on a smallish team, but I used to work on a team that had ~200 engineers committing to the same monolith. Effectively, the cost of writing public-by-default methods was essentially the same as maintaining a library: It wasn’t clear to me who would use my class, when, or how. My approach is private-by-default: Make the API as small as possible.

    If, in fact, there is a future need to re-use some abstraction that is currently used in a private method, I am happy to refactor later and make that functionality available purposefully.

    Inline RBS type declaration

    Experimental syntax, but this mode of type declarations are something I can get on board with!

    Since it’s using #:: and # @rbs as special comments, they can probably be recognized by syntax highlighters and other tooling.

    Lesser Known Rails Helpers to Write Cleaner View Code

    I’ve been writing Rails for over 12 years, and some of these are new to me! I wonder if I’ll remember that they exist next time I have opportunity to use them!

    Read on →