Skip to content

Instantly share code, notes, and snippets.

View quad's full-sized avatar

Scott Robinson quad

View GitHub Profile
@quad
quad / 0-a-logging-api.md
Last active April 23, 2024 13:59
Structured logging deprecates log levels [DRAFT]

Structured logging deprecates log levels

I read [an argument for only two log levels: INFO and ERROR][only-info-error]. I [responded][log-response] essentially saying:

  1. I lightly agree that we could get away with two log levels.
  2. I strongly disagree that we only need two ways to log.

Like the blog post's author, most of systems that I've worked on have had poor logging practices. But unlike the blog post's author, I strongly suspect that's because most logging APIs offer poor affordances.

@quad
quad / 0-hybrid-service-architecture.md
Last active March 16, 2024 02:04
The Hybrid Service Architecture

The Hybrid Service Architecture

I haven't found a description of the service architecture I frequently see; but, the Internet is lousy with descriptions of three tier and event driven architectures.

This write-up is for Future Me to point at when asked how to design a network service.

tl;dr

  • A server cluster, scaled horizontally
  • A queue cluster, scaled vertically or sharded
@quad
quad / 0-unnamed-architecture.md
Last active April 14, 2024 05:45
What is this architecture called?

What is this architecture called?

I rarely see the classical three-tier architecture in the wild; I frequently see a different architecture.

I don't know this architecture's name. Do you?

The Three-Tier Architecture

The "three-tier architecture" has been the reference pattern for Internet services:

@quad
quad / classics.md
Created December 29, 2023 10:09
The Classics
@quad
quad / 0-service-start.md
Last active December 13, 2023 09:17
Why can't I start a service?

Why can't I start a service?

  • I can start a thread, if I want shared memory parallelism
  • I can start a process, if I want shared storage parallelism
  • I cannot start a service, if I want shared network parallelism

What would it take to add a start API?

Overly literal examples

@quad
quad / 0-interceptors-are-functions-too.md
Last active April 10, 2024 09:06
Interceptors Are Functions Too

Interceptors Are Functions Too

I could not agree more with my colleague and friend Travis Johnson's opinion that "[INTERCEPTORS ARE SO COOL][iasc]!" In that post, he succinctly describes the [Interceptor pattern][pattern] as used adroitly by [OkHttp][okhttp]. But, as is often the case, I believe a complicated object-oriented pattern obscures the simple functional gem within it.

What is an Interceptor?

I'll quote liberally from [OkHttp's documentation on the topic][okhttp-interceptor]:

Interceptors are a powerful mechanism that can monitor, rewrite, and retry calls. […] >

@quad
quad / 1-the-false-application-library-dichotomy.md
Created June 14, 2023 18:55
(DRAFT) The false Application / Library dichotomy
  • "Libraries need to be semver"
  • "Libraries need to have shallow dependencies"
  • "Libraries need to protect their abstractions / not expose their internal implementation details"
@quad
quad / 0-modular-errors-with-rusts-thiserror.md
Last active April 20, 2024 07:22
Modular Errors with Rust's thiserror

I've been writing Rust full-time with a small team for over a year now. Throughout, I've lamented the lack of clear best practices around defining error types. One day, I'd love to write up my journey and enumerate the various strategies I've both seen and tried. Today is not that day.

Today, I want to reply to a blog post that almost perfectly summarised my current practice.

Go read it; I'll wait!


@quad
quad / update
Created February 23, 2023 10:16
#!/bin/bash
set -euo pipefail
start_sudo_session() {
sudo --validate
while :; do
kill -0 $$ &>/dev/null
sudo --non-interactive --validate
@quad
quad / Code.gs
Created October 28, 2020 03:50
Block out my work calendar with my personal events
function hashify(hash, [key, value]) {
hash[key] = value;
return hash;
}
function eventId(event) {
if (event.isRecurringEvent()) {
return event.getId() + "-" + event.getStartTime().toISOString() + "-" + event.getEndTime();
}