RSSAmplifier

Blog

Stuart Hinson

stuarth.github.ioRSS feed ↗9 posts

Latest posts

Rocket v0.5 Error Handling Best Practices

A common question in #rocket is how to go beyond the basics in error handling. Specifically, there’s a bit of a jump that’s needed to connect the dots between defining a custom error type (e.g. with thiserror ) and the Responder trait . We can put these together and write handlers with idiomatic early returns, e.g. #[derive(Error, Debug)] pub enum Error { #[error( "HTTP Error {source:?}" )]…

Effective (and Simple!) Predictive Recommendations

I want to give a quick illustration of the idea that effective applications of machine learning – especially early versions – can be almost embarrassingly simple. This is the broad strokes of a system I implemented that produced a substantial lift in revenue for a large online marketplace. This marketplace is a bit unusual in that its products are all one of a kind. Every day, we’d list a new…

Connecting Remote Controlled Blinds to Alexa Smart Home

My intuition is to begin with a bit about the pragmatic motivations for the project, but if I’m being honest this came from a place of ‘I bet I could do this’ rather than ‘what my life needs isn’t remote controlled blinds, it’s voice controlled blinds’. Anyway. My coworking space recently bought some remote controlled blinds. This is a story about how I connected them to Alexa. The idea is to have…

Building Clojure projects with the Jenkins Kubernetes Plugin

The Jenkins Kubernetes plugin is a very cool bit of tech that allows Jenkins to dynamically provision workers from a pool of Docker hosts managed by Kubernetes. Setting up a worker with lein is straightforward. With the Kubernetes plugin installed, visit your Jenkins configuration page and add a pod template along the lines of The Docker image url refers to this Quay.io repository , based on a…

Understanding Pedestal Interceptors and Selectively Injecting a ClojureScript REPL

Pedestal represents interceptors, its analog to Ring middleware, as data. Let’s look at how we can use that to conditionally inject a ClojureScript REPL into responses. Pedestal Terminology Two working definitions as we start Interceptor - a record containing keys corresponding functions for execution stages. Serves an analogous role to middleware in Ring. context - a map with all data relating to…

Pixie Pi

Pixie is a Clojure-inspired lisp that has a quick startup time and nice FFI support that allows it to make use of existing C libraries, making it a nice option for working with the Raspberry Pi. Installing Pixie Meeting Dependencies From a base Raspbian install, Pixie’s dependencies (as of eb5886ff95) except for libuv-dev can be satisfied using aptitude sudo apt-get install libffi-dev libedit-dev…

Error handling in Pedestal 0.4.0

Pedestal 0.4.0 includes io.pedestal.interceptor.error/error-dispatch , which uses core.match to make error handling very tidy. For example ( def my-error-handler ( error-int/error-dispatch [ context ex ] ;; match errors from body-params interceptor { :interceptor :io.pedestal.http.body-params/body-params } ( let [ response ( -> ( ring.util.response/response "Invalid data given" ) :status 400 )] (…

Configuring CSRF protection in a simple Clojure / Pedestal App

OWASP has an excellent description of CSRF attacks and why they’re a concern. The tl;dr is, without safegaurds, an attacker can cause users to take unintended actions on your app . It’s well worth spending a few minutes on the link above if you’re not familiar. Using io.pedestal.http.csrf to prevent attacks Pedestal’s io.pedestal.http.csrf namespace implements the synchronizer token pattern that…

Surprising timeout chan interactions in Clojure's core.async

note that this behavior applies to core.async 0.1.338.0-5c5012-alpha The issue distilled Let’s measure the time it takes to create two timeout chans, close one, and read from the other. ( let [ a ( timeout 100 ) b ( timeout 100 ) t0 ( System/currentTimeMillis )] ( close! a ) ( <!! b ) ( - ( System/currentTimeMillis ) t0 )) ;; => 0 What happened? Why don’t we see a value ~100ms corresponding to b…