• Clojure/West: My favourite sessions

  • Clojure/West: How Clojure Saved My Chickens

    Prepare Beagle Bone Black

    • install JVM
    • install lein - it doesn’t like running as root and you only get permissions on the pins as root.
    • add non-root user
    • pin permissions magic for user
    • startup and logging

    Pin reading & writing

    • digital pins
    • analog input pins


    • some active when open
    • some active when closed


    • four gates to control a motor


    • door misses the button and drains the battery - solved with a retry mechanism
    • status led to communicate problems

    Hardware & Clojure


    • fun
    • something in the physical world moves
    • physical systems are asychronous / concurrent
    • high level capabilities of Clojure


    • JVM isn’t light
    • full OS required


    Shared repos for controlling hardware using Clojure.

  • Clojure/West: Clojure at Scale

    What kind of scale?

    • 70 lein projects
    • 20 services


    • structuring code
    • multiple projects
    • choosing libraries
    • logging
    • commons daemon
    • infrastructure as code

    structuring code

    • use component
    • component lets you use dependency injection in your tests
    • component can help you decide where to put code

    multiple projects

    • multiple lein projects
      • navigating code leads you to read-only code (i.e. in your local maven repository)
    • write a script to merge all your projects and dependencies together so that you can run all your tests in one place

    choosing libraries

    • be cynical
    • libraries without dependencies are safe choices
    • any library that does any network operation - caution! (e.g. timeout guarentees, queuing, async/sync IO)


    • LOGBack, Log4j, Java Logging API, SLF4J
    • use SLF4J
    • use the same facade for all logging configuration

    commons daemon

    infrastructure as code

    • (see video)


    • Release it! (book)
    • Component (youtube)
    • Language of the system (youtube)
    • The Pheonix Project (book)
  • Docker: oops don't expose postgres to the internet

    Do you spot the mistake here?

    docker run -p 5432:5432 --name postgres -d postgres

    The reason I’m exposing port 5432 is so that I can run psql on the Docker host. But, but but. I’m running this on digitalocean so this exposes port 5432 to the internet at large!

    The command above is the equivalent of:

    docker run -p --name postgres -d postgres

    What I intended was:

    docker run -p --name postgres -d postgres

    That binds to the local loopback address which is what I wanted.

    As a side note if you have a docker image with psql that’s linked to the postgres container then simply using docker exec is the way to go. E.g.:

    docker run --name postgres -d postgres
    docker exec -t -i some-image-with-psql --link postgres:pg psql any-arguments-you-want-to-pass-to-sql

    Link establishes environment variables (as the host ip address varies). In this case PG_PORT_5432_TCP_ADDR, PG_PORT_5432_TCP_PORT.

  • Docker: cannot allocate memory

    I was running into this error on my digitalocean box:

    FATA[0000] Error: Untar fork/exec /usr/bin/docker: cannot allocate memory

    The fix for me was to add swapspace. By default my digitalocean droplet didn’t come with any swap!

    dd if=/dev/zero of=/root/myswapfile bs=1M count=1024
    chmod 600 /root/myswapfile
    mkswap /root/myswapfile
    swapon /root/myswapfile
  • Clojure/West unsession: 100% remote work

    The good

    • more potential hires
    • lower overhead cost -> higher compensation
    • no forced commute -> improved quality of life
    • more diverse team mates
    • being able to do laundry and other chores
    • able to spend time with friends that work irregular hours
    • pets!

    The bad

    • a meeting you aren’t invited to
    • internet connection fails or poor quality
    • graphical editors -> hard for both parts of a pair
    • time zones -> problematic (hard to do hand-offs, need overlapping time)


    • symmetry for pairing (i.e. neutral environment so that both parties have the same experience)
    • low cost to communication (e.g. slack integration to share a tmux link to your pairing setup)
    • microphone recommendation “blue snowball”
    • —> “standown”: drink a beer, talk about what didn’t work that day, etc <—
    • advertising discussions ahead of time so that folks can join if they want to
    • use low latency tools
  • Clojure/West: State of Clojure

    Clojure 1.7

    • coming in the next few weeks


    • these evaluate to transducers now:

      (filter odd?) (map inc) (take 5)

    • and can be composed:

      (comp ; similar behaviour to thread-last macro (filter odd?) (map inc) (take 5))

    • xf is the notation for a transforming function (transducer)
    • (sequence xf (range 1000)) is the way to maintain the laziness and use transducers
    • (a/chan xf 10) is the core.async extention for applying transducers before putting on the channel

    Reader conditions

    • portable code across Clojure platforms
    • new file extension .cljc
    • reader conditionals:

      ;; choose expression based on platform #?(:clj (java.util.Date.) :cljs (js/Date.))

      ;; and a splicing version [:a :b #?@(:clj [:c :d] :cljs [:e :f]]


    ..snip.. things are faster

  • Clojure/West: Staying SAFE: A foundation for Clojure applications

    SAFE: Sonian Archive File Engine

    • indexes incoming emails for search
    • application, library, framework -> foundation

    New service, old problems

    • deploy
    • configure
    • debug
    • flexible

    • how do I run code on startup?
    • how do I run periodic tasks?
    • how do I give it commands?
    • how do I distribute work over multiple instances?


    • finds configuration on the classpath
    • exposes values via config method - e.g. (config :core :app)
    • open sourced as carica


    • startup doinit
    • shutdown dofini
    • deftick and deftock for hourly tasks
    • dostatus for reporting health status
    • defadmins for running commands - vai safectl
    • open sourced as carousel


    • defined by defadmin
    • used to interact with the services e.g.
      • safectl status
      • safectl util repl
      • safectl imports emls –account 43 –url s3://walrus/bucket.eml

subscribe via RSS