Skip to content

Instantly share code, notes, and snippets.

View nh2's full-sized avatar

Niklas Hambüchen nh2

View GitHub Profile
@nh2
nh2 / mmap-memory-usage.c
Created December 7, 2020 19:43
Demo of how mmap() affects VIRT, RES, SHR memory usage in Linux
// Demo of how mmap() affects VIRT, RES, SHR memory usage in Linux.
//
// A useful resource for more background:
// https://techtalk.intersec.com/2013/07/memory-part-2-understanding-process-memory/
// Required for:
// * `O_TMPFILE`
// * `fallocate()`
#define _GNU_SOURCE
@nh2
nh2 / SocketUtils.hs
Created July 13, 2019 20:18
Check whether a port is open in Haskell
module SocketUtils
( isPortOpen
, simpleSockAddr
) where
import Data.Word (Word8)
import Foreign.C.Error (Errno(..), eCONNREFUSED)
import GHC.IO.Exception (IOException(..))
import Network.Socket (PortNumber, socket, connect, close', Family(AF_INET), SocketType(Stream), SockAddr(SockAddrInet), tupleToHostAddress)
import UnliftIO.Exception (try, bracket, throwIO)
@nh2
nh2 / TemplateHaskell-recompilation-problem.md
Created October 31, 2019 11:12
TemplateHaskell: The [TH] Recompilation Problem

"The [TH] Recompilation Problem"

Usually, when you use ghci's :reload or ghc --make (with -O0 to disable unfoldings which are used for cross-module inlining), after changing implementation code of functions, GHC will incrementally recompile only the modules you changed, making for a fast development experience when iterating on implementation details.

(When you change API like functions types, export lists, etc.,

@nh2
nh2 / nixos-install-hetzner-cloud.sh
Last active June 3, 2022 09:54
Implementation of nh2's pubkey into https://github.com/nix-community/nixos-install-scripts/blob/master/hosters/hetzner-cloud/nixos-install-hetzner-cloud.sh (Script to install NixOS from the Hetzner Cloud NixOS bootable ISO image. Wipes the disk!)
#! /usr/bin/env bash
# Script to install NixOS from the Hetzner Cloud NixOS bootable ISO image.
# Wipes the disk!
# Tested with Hetzner's `NixOS 20.03 (amd64/minimal)` ISO image.
#
# Run like:
#
# curl https://nh2.me/nixos-install-hetzner-cloud.sh | sudo bash
#
#!/usr/bin/env bash
# Installs NixOS on a Hetzner server, wiping the server.
#
# This is for a specific server configuration; adjust where needed.
#
# Prerequisites:
# * Update the script to adjust SSH pubkeys, hostname, NixOS version etc.
#
# Usage:
@nh2
nh2 / example-output.txt
Created April 19, 2022 14:15
Process `ghc -v` output, summarising where time is spent.
# ./ghc-performance-categorizer.py ghci-v-output-1.txt --sort-by time
TASK time ms mem MB
------------------------------------------------
systool:cpp 4 2
systool:merge-objects 11 3
Simplify 38 68
ByteCodeGen 70 164
initializing 72 119
systool:as 175 68
@nh2
nh2 / mv-tree.py
Created January 23, 2022 07:18
Tool to move contents of one directory tree into another, safely.
#! /usr/bin/env python3
# Moves contents of one directory tree into another, safely.
import argparse
import filecmp
import shlex
import sys
from dataclasses import dataclass
@nh2
nh2 / configuration.nix
Last active October 14, 2021 11:47
NixOS configuration for nh2's mail server presentation (https://nh2.me/recent/Running-your-own-mailserver.pdf)
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).
{ config, pkgs, ... }:
let
floatingIPv4 = "95.216.183.106";
floatingIPv6 = "2a01:4f9:c01f:65::1";
in
{
@nh2
nh2 / FoldMapA.hs
Created November 18, 2016 20:43
foldMapA, Applicative-action folding in Haskell
-- Written for GHC 8.0
import Data.Foldable (foldr')
-- The other day I had the feeling that if I can write
--
-- minumumABy :: (Applicative f)
-- => (b -> b -> Ordering) -> [a] -> (a -> f b) -> f (Maybe b)
--
@nh2
nh2 / tcp-nodelay.md
Last active November 18, 2020 07:06
Understanding TCP_NODELAY

I believe the following is the best way to work with Nagle's algorithm / TCP_NODELAY / TCP_CORK.

It is described in this RedHat manual and the verdict is:

  • Set TCP_NODELAY = 1, always.
  • If you can batch data for sending by creating a buffer manually, or using writev(), prefer that.
  • If you cannot (e.g. "when using different libraries that provides abstractions for layers" from the above manual):
    • Set TCP_CORK = 1, then write the data, then set TCP_CORK = 0.
  • This builds a packet in kernel space and then flushes it out.