Skip to content

Instantly share code, notes, and snippets.

Tony Holdstock-Brown tonyhb

Block or report user

Report or block tonyhb

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
@tonyhb
tonyhb / sourcing.md
Last active Aug 22, 2018
Event sourcing thoughts
View sourcing.md

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.

View genesis_public_key
04bcdf33e02091a0cb21a18e2d66c9bb886b7fe6e7c04c78ff927da0a96f7d05da2e27014611ae48299b93c31157fe06b53173cf8d5188cf3f00ed05b5f86d11e4
View fsm.re
/* 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,
View react-native.nix
{ 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
View gist:c78c953b900f3a9eb63ddb4fc8686a0b
# 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 Aug 29, 2015
Exposing atomic and transactional database methods
View page.go
package models
import (
"github.com/jmoiron/sqlx"
"github.com/tonyhb/govalidate"
)
type Page struct {
Id int64
Name string
@tonyhb
tonyhb / click.rb
Created Sep 18, 2014
RackRequestCounter
View click.rb
# 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 Aug 29, 2015
Using variable functions to make testing easier
View main.go
// 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 {
View gist:4061f439d4f221767c12
set nocompatible " be iMproved
filetype off " required!
set rtp+=~/.vim/bundle/vundle/
call vundle#rc()
Bundle 'gmarik/vundle'
" Plugins here
View index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bitcoin Payroll</title>
<script src="/assets/js/libs/modernizr.js"></script>
<link rel="stylesheet" href="/assets/css/bootstrap.css" />
<link rel="stylesheet" href="/assets/css/flat-ui.css" />
<link rel="stylesheet" href="/assets/css/app.css" />
</head>
You can’t perform that action at this time.