Skip to content

Instantly share code, notes, and snippets.

Avatar

Bob Gregory bobthemighty

View GitHub Profile
View production-readiness-checklist.md

Production Readiness April 2018

Although the pace of change at Made has slowed over the last 12 months, we are still testing new techniques and re-examining best practices. It's useful to periodically reflect on what good practice looks like and make sure we're spreading that knowledge to our dev teams. This is a quick guide to what the Ops team need from developers in 2018. If your systems don't comply with these guidelines, you should chat to a friendly ops person so we can help you prioritise and fix issues.

Operator.MD

Ops can't operate your system if they don't know how to work it. Every system should have an operators.md file in the root of the github repository that describes:

  • What the system does.
  • What the business impact of an outage is.
View keybase.md

Keybase proof

I hereby claim:

  • I am bobthemighty on github.
  • I am pathogenix (https://keybase.io/pathogenix) on keybase.
  • I have a public key ASCMDRUTDeWMXR5rO3tRehTbTMjSs00XaWOhIFjSxp8WBQo

To claim this, I am signing this object:

View walking-skeleton.md
  • Connect to eventstore using consul for discovery
    • Do you want to use Consul-template or a consul client for this? CT is going to be easier for AtomicPuppy, I think.
  • Read an event with atomicpuppy and log it
    • Suggest starting with the heartbeat message that we already use for ERP and Availability.
  • Restart the app on SIGHUP
  • Set up proper json logging using the msg_id and msg_type fields
  • Metric: Eventstore response code
  • Metric: Eventstore latency
    • These two may not be possible without changing AtomicPuppy, in which case we should probably not put them in scope.
  • Metric: Event processing time
View foo.py
def doSomethingThatMightFail():
attempts = 0
success = False
retry = True
while retry and not success:
success = call_the_service()
if attempts ++ > MAX_ATTEMPTS:
View rsyslog.conf
module(load="imuxsock" SysSock.Use="on")
module(load="omhiredis")
input (type="imuxsock" Socket="/dev/log")
template(name="plain-syslog"
type="list") {
constant(value="{")
constant(value="\"@timestamp\":\"") property(name="timereported" dateFormat="rfc3339")
View keybase.md

Keybase proof

I hereby claim:

  • I am bobthemighty on github.
  • I am pathogenix (https://keybase.io/pathogenix) on keybase.
  • I have a public key whose fingerprint is 49CE FED3 0B35 4794 00CA 20C6 710A 1AA3 2A42 69F8

To claim this, I am signing this object:

View glossary.md

Command

Commands encapsulate requests to DO something in the system. Each command uses the imperative tense ("CreateWidget", "MakeCustomerHappy", "UseTheForce"). A command is an immutable value object with no behaviour of its own. Commands are processed by Command Handlers. Each command must have exactly one command handler.

class CreateWidgetCommand
{
   function __construct($widgetColour, $widgetHeight, $widgetWidth){ ...}
   
View gist:921a89da42e12b09d965
will_respond_with(
{
status: 200,
headers: {
'Content-Type': 'application/atom+xml'
},
schema: {
# this is the document we expect the mock server to return.
example: '<atom:entry>
<atom:title>Atom-Powered Robots Run Amok</atom:title>
View response
<!doctype html>
<html lang="en_GB" ng-app="ogs">
<head>
View gist:e9c0021c50708a63d604
using(var cn = new SqlConnection(MA_CONNECSHUNS))
using (var cmd = new SqlCommand(MA_QUERIES, cn))
{
cn.Open();
using (var reader = cmd.ExecuteReader())
while (reader.Read())
{
SqlXml xml = reader.GetSqlXml(1);
using (var xr = xml.CreateReader())