Skip to content

Instantly share code, notes, and snippets.

View tonyhb's full-sized avatar
🕳️
void

Tony Holdstock-Brown tonyhb

🕳️
void
View GitHub Profile
@tonyhb
tonyhb / go.yml
Last active February 19, 2021 19:40
Randomize go package specs on github actions
name: Build & Test
on:
push:
branches: [ develop, master ]
pull_request:
branches: [ develop, master ]
jobs:
@tonyhb
tonyhb / sourcing.md
Last active March 26, 2022 20:16
Event sourcing thoughts

I've been planning out an event sourcing like system for our healthtech startup, and you're definitely right re namespacing and versioning.

I explicitly keep a version in the event - which is a date. It's similar in how Stripe versions their API. We're also planning to handle the events in the same way as stripe's API: each event has side effects; the side effects may change depending on the version and each version has its own application logic (cascading, so you can have 2018-08-01 run all of 2018-07-30 plus its own changes).

This lets us replay events as they happened, run an event using two different versions and perform only the diffs etc.

Our system is probably not a typical CQRS/event sourcing setup.

The event system itself idempotent: you take an event with all input data necessary to run the event (form data, necessary current state), so the system can run independently. This means that every event is typed such that the input data dictates what is necessary.

@tonyhb
tonyhb / genesis_public_key
Created March 6, 2018 01:36
genesis_public_key
04bcdf33e02091a0cb21a18e2d66c9bb886b7fe6e7c04c78ff927da0a96f7d05da2e27014611ae48299b93c31157fe06b53173cf8d5188cf3f00ed05b5f86d11e4
@tonyhb
tonyhb / fsm.re
Created January 11, 2018 00:28
fsm/dfa
/* result represents either a success or an error for an operation. It can hold
a resource of any type - ie. a user, treatment etc. */
type result('resource) =
| Ok('resource)
| Error('resource, string);
/* Event represents a single event within our system */
type event('data, 'resource) = {
/* The ID of the user authoring the event */
author: string,
{ pkgs ? import <nixpkgs> {} }:
let
jdk = pkgs.jdk8;
androidsdk = pkgs.androidenv.androidsdk_6_0_extras;
fhs = pkgs.buildFHSUserEnv {
name = "android-env";
targetPkgs = pkgs: with pkgs; [
androidsdk
bash
@tonyhb
tonyhb / gist:c78c953b900f3a9eb63ddb4fc8686a0b
Last active February 23, 2018 00:29
Debian machine setup
# Install kernel 4.14
echo 'deb http://http.debian.net/debian stretch-backports main' | sudo tee /etc/apt/sources.list.d/stretch-backports.list
sudo apt-get update
sudo apt-get -t stretch-backports install linux-image-amd64
# Install Docker
sudo apt-get -y install \
apt-transport-https \
ca-certificates \
curl \
@tonyhb
tonyhb / page.go
Last active August 29, 2015 14:18
Exposing atomic and transactional database methods
package models
import (
"github.com/jmoiron/sqlx"
"github.com/tonyhb/govalidate"
)
type Page struct {
Id int64
Name string
@tonyhb
tonyhb / click.rb
Created September 18, 2014 20:48
RackRequestCounter
# spec/support/click.rb
module Capybara
module Node
class Element < Base
# Override the default implementation of click so that whenever we click
# on something, we also wait for any ajax requests to finish.
def click
synchronize { base.click }
@tonyhb
tonyhb / main.go
Last active August 29, 2015 14:05
Using variable functions to make testing easier
// By assigning next to a variable we can swap out the hello() function in testing with a custom
// implementation
var h = hello
func main() {
fmt.Println(n())
}
func hello() string {
set nocompatible " be iMproved
filetype off " required!
set rtp+=~/.vim/bundle/vundle/
call vundle#rc()
Bundle 'gmarik/vundle'
" Plugins here