Skip to content

Instantly share code, notes, and snippets.

@tautologicc
tautologicc / gist:ae97524b8a935e9ffa81c1f7e2fc408d
Created September 11, 2020 05:43 — forked from chanks/gist:7585810
Turning PostgreSQL into a queue serving 10,000 jobs per second

Turning PostgreSQL into a queue serving 10,000 jobs per second

RDBMS-based job queues have been criticized recently for being unable to handle heavy loads. And they deserve it, to some extent, because the queries used to safely lock a job have been pretty hairy. SELECT FOR UPDATE followed by an UPDATE works fine at first, but then you add more workers, and each is trying to SELECT FOR UPDATE the same row (and maybe throwing NOWAIT in there, then catching the errors and retrying), and things slow down.

On top of that, they have to actually update the row to mark it as locked, so the rest of your workers are sitting there waiting while one of them propagates its lock to disk (and the disks of however many servers you're replicating to). QueueClassic got some mileage out of the novel idea of randomly picking a row near the front of the queue to lock, but I can't still seem to get more than an an extra few hundred jobs per second out of it under heavy load.

So, many developers have started going straight t

1. Separation of immutable and mutable logic

Quite a lot of different people have been on the same trail of thought. Gary Bernhardt's formulation of a "functional core, imperative shell" seems to be the most voiced.

"Boundaries" - Gary Bernhardt

"Imperative shell" that wraps and uses your "functional core".. The result of this is that the shell has fewer paths, but more dependencies. The core contains no dependencies, but encapsulates the different logic paths. So we’re encapsulating dependencies on one side, and business logic on the other side. Or put another way, the way to figure out the separation is by doing as much as you can without mutation, and then encapsulating the mutation separately. Functional core — Many fast unit tests. Imperative shell — Few integration tests

https://www.youtube.com/watch?v=yTkzNHF6rMs

@tautologicc
tautologicc / presentation-tips.md
Created May 28, 2021 16:10 — forked from macintux/presentation-tips.md
Public speaking tips
@tautologicc
tautologicc / Makefile
Last active April 18, 2022 17:13
Self-documented Makefile
.SUFFIXES:
help: Makefile ## display this help and exit
@echo 'Usage:'
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $< | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " %s\n %s\n", $$1, $$2}'
hello: ## emit the "hello, world" message
@echo Hello, world!
.PHONY: help compose
@tautologicc
tautologicc / lmdb.tcl
Created April 6, 2022 14:48 — forked from antirez/lmdb.tcl
LMDB -- First version of Redis written in Tcl
# LVDB - LLOOGG Memory DB
# Copyriht (C) 2009 Salvatore Sanfilippo <antirez@gmail.com>
# All Rights Reserved
# TODO
# - cron with cleanup of timedout clients, automatic dump
# - the dump should use array startsearch to write it line by line
# and may just use gets to read element by element and load the whole state.
# - 'help','stopserver','saveandstopserver','save','load','reset','keys' commands.
# - ttl with milliseconds resolution 'ttl a 1000'. Check ttl in dump!
@tautologicc
tautologicc / paren.c
Last active May 29, 2022 17:27
C program that verifies that every opening parenthesis is followed by a closing one
// SPDX-License-Identifier: CC0
extern int write();
int
main(int argc, char *argv[])
{
if (argc < 2) {
static char usage[] = "usage: paren STRING\n";
write(2, usage, sizeof usage);
return 2;
@tautologicc
tautologicc / oss.md
Last active November 12, 2023 14:43
@tautologicc
tautologicc / x11_forwarding_macos_docker.md
Created November 7, 2022 01:00 — forked from sorny/x11_forwarding_macos_docker.md
X11 forwarding with macOS and Docker

X11 forwarding on macOS and docker

A quick guide on how to setup X11 forwarding on macOS when using docker containers requiring a DISPLAY.

This guide was tested on:

  • macOS Catalina 10.15.4
  • docker desktop 2.2.0.5 (43884) - stable release
  • XQuartz 2.7.11 (xorg-server 1.18.4)

Step-By-Step Guide

@tautologicc
tautologicc / .zshrc
Last active October 31, 2023 15:25
Start ssh-agent, with Apple keychain support
if [ "$(uname)" = Darwin ]; then
alias ssh-add='ssh-add --apple-use-keychain'
fi
export SSH_ENV="$HOME/.ssh/env"
if [ -e "$SSH_ENV" ]; then
. "$SSH_ENV"
fi
@tautologicc
tautologicc / README.md
Created December 4, 2022 21:27 — forked from lithdew/README.md
Differences between Linux and Mac for sockets.
  1. A listening socket blocked on accept() can be unblocked by calling shutdown(socket_fd, SHUT_RD) on Linux. On Mac, calling shutdown(socket_fd, SHUT_RD) on a listening socket that is blocked on accept() will return an error ENOTCONN. To unblock a listening socket blocked on accept() on Mac requires calling close(socket_fd), which will cause the blocking accept() call to return an error EBADF.

Therefore, in order to unblock a socket on accept() on both Mac/Linux, shutdown() should not be relied on. Rather, an async cancellation scheme (such as cancellation tokens in .NET) should be used instead to unblock the call to accept().

  1. When a socket is instantiated and subsequently registered to epoll, or when a socket is shut down (via. shutdown() or setsockopt(SO_LINGER)) on Linux, epoll will be notified with EPOLLHUP on the socket. On Mac, kqueue will only notify when a socket is shut down (via. shutdown() or setsockopt(SO_LINGER)) by sending a EV_EOF notification on filters EVFILT_READ, and EVFILT_WRITE.

Thi