Tom Peters

Software developer and product manager from Buffalo, NY. I build products people love using. Huge fan of Go. Creator of SqMGR, Names in a Hat, and Monday Night Poker.

Go

My primary language for building reliable, performant backend services and APIs.

  • SqMGR is a site for managing football squares.
  • Monday Night Poker is an online poker site for dealer's choice style games with friends.
  • Sibyl is an application for agile scrum planning sessions.
  • argon2id is an open-source library for secure password hashing.
  • pwned checks passwords against the haveibeenpwned database.
func (l *RateLimiter) Limit(next http.Handler) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    ip := getIP(r)
    limiter := l.getVisitor(ip)

    if !limiter.Allow() {
      http.Error(w, http.StatusText(http.StatusTooManyRequests),
        http.StatusTooManyRequests)
      return
    }

    next.ServeHTTP(w, r)
  })
}

JavaScript

Building beautiful, mobile-friendly front-ends with Vue, React, and vanilla JS.

  • SqMGR is a single-page application built with Vue for managing football squares.
  • Tournament of Champions features a Go backend with vanilla JS frontend.
  • This site was built with vanilla JS and Vite.
send(action, subject, cards, additionalData) {
  const context = uuid()
  this.ws.send(JSON.stringify({
    action, subject, cards, additionalData, context,
  }))

  return new Promise((resolve, reject) => {
    const timeout = setTimeout(() => {
      reject('did not receive response from server')
      delete(this.context[context])
    }, 2000)

    this.context[context] = { resolve, reject, timeout }
  })
}

Swift

Two apps on the App Store, kept current with Apple's best practices.

  • Names in a Hat is a randomized name drawing app I've maintained since 2009.
  • Teddy Draw is a toddler-friendly drawing app with no ads or complicated UI.
// Draw all names ahead of time to avoid the scenario
// where the last two names are the same person
func drawForSecretSanta() {
  outerLoop: while true {
    resetDraw()
    var secretSantaResults = [DrawingResult]()
    for name in hat.names {
      while true {
        guard let result = super.draw() else {
          fatalError("could not call draw()")
        }
        if name != result.name {
          result.giverName = name
          secretSantaResults.append(result)
          break
        }
        if super.isComplete() { continue outerLoop }
        guard super.undoDraw() else {
          fatalError("could not undoDraw()")
        }
      }
    }
    // ...

Perl

Over 15 years of experience writing highly performant, modern Perl.

  • Built RESTful APIs serving billions of requests per month using Apache Solr and Cassandra.
  • Built an ETL system for ingesting movies, TV shows, and news from thousands of sources.
  • Open sourced Test::MockPackages for unit test development.
sub called {
  my ( $self, $called ) = @ARG;

  if ( !looks_like_number( $called ) || $called < -1 ) {
    croak( '$called must be an integer >= -1' );
  }

  $self->{_called} = $called;

  return $self->_validate();
}

Databases

PostgreSQL is my go-to RDBMS, with experience in MySQL/MariaDB, Solr, Riak, and Cassandra.

CREATE FUNCTION adjust_balance(
  _players_tables_id bigint, _current_balance int,
  _adjustment int, _game_id bigint, _reason text
) RETURNS boolean LANGUAGE plpgsql AS $$
DECLARE
  _previous_balance int;
  _next_balance int;
BEGIN
  SELECT INTO _previous_balance balance
    FROM players_tables WHERE id = _players_tables_id FOR UPDATE;

  IF _previous_balance != _current_balance THEN
    RAISE EXCEPTION 'balance has changed';
  END IF;

  _next_balance := _previous_balance + _adjustment;
  INSERT INTO players_tables_transactions (...) VALUES (...);
  UPDATE players_tables SET balance = _next_balance WHERE id = _players_tables_id;
  RETURN TRUE;
END; $$;

Kubernetes

Docker and Kubernetes advocate. Using GitHub Actions for CI/CD pipelines.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sqmgr-api
spec:
  template:
    spec:
      containers:
        - name: sqmgr
          image: ghcr.io/sqmgr/sqmgr-api:latest
          args: ['-migrate']
          envFrom:
            - secretRef:
                name: sqmgr-config
          volumeMounts:
            - mountPath: /opt/sqmgr/jwt-keys
              name: jwt-keys
          readinessProbe:
            httpGet:
              port: 8000
              path: /
      volumes:
        - name: jwt-keys
          secret:
            secretName: sqmgr-jwt-keys