Mavnn's blog

Stuff from my brain

Working From Home, Pandemic Edition

There's an "organic" version of this post at on Google Docs which may receive some edits over time. But I also wanted to reach a broader audience.

Many of you reading this document will be either:

  • managers asking people to work from home for the first time, with very little warning
  • workers who do not normally work from home being asked to do so on short notice

We’ll try and signpost items that might be of especial relevance to one group or the other, but a lot of this advice will be relevant to everyone.

Who are we?

I (Michael Newton) started this document as a response to several queries I’ve had about home working in the light of the CoVid19 pandemic. I’ve been working from home for years, and helping home educate our son at the same time.

I’m currently working with NoRedInk where about half of our workforce is normally remote (we call them the “Remotians”) - but since Friday we’ve moved to fully remote working for the duration of the current events. We have a history of remote working that goes back to soon after the company was founded, and forced ourselves to get it right by hiring two remote VPs into the senior leadership team.

What is this document?

This document is partly being created to help and support the NoRedInkers who have had to unexpectedly become Remotians overnight, and partly a place for the Remotians among us to share what we’ve learned over the years.

Anyone with a NoRedInk email address can request editing access to this document, and it contains the collective wisdom of a group of people. That means you’ll get a variety of views and approaches below. Also NRIers: that means don’t post all the company internal secrets here or I’ll be in lots of trouble 😅.

Getting Started

You are doing remote working on hard mode. Most people who start remote working have time to prepare, to think through the logistics and to set up home and life in a sensible, considered way.

You probably do not, and if the indications from Asia and most of Europe are accurate, you will probably also shortly have to deal with school and child care being closed and adjusting your home life to deal with physical distancing. This is not normal conditions to be working under, and means that certain (normally good!) home working advice may not be possible or helpful for you right now. That means your first priority is looking after yourself and family and your second priority is being an effective remote worker. It’s okay for this to feel hard at times!

How to Think (Everyone)

Remote working requires a fundamentally different way of thinking about “work” than being in the office does. You can’t rely on just counting the time from when you arrive in the office to the time you leave as “being at work.” So; how do you think instead?

  • Do try and set aside time that is “work time” and time which is not. You are not on call 24-7 just because you have the company laptop at home.
  • Do be deliberate about staying in touch with your co-workers about what you are doing and when. There is a lot of communication that happens in an office that you will have to make an effort to deliberately replicate as a remote worker. There’s a whole section on this below!
  • Don’t time your work to the second in your own house. At work you take loo breaks, coffee breaks, talk to co-workers about the weekend, and any number of other things without clocking off. Some level of interruption of your day is normal, expected, and you are not cheating your boss by dealing with it.
  • Do be honest with yourself about this: grabbing a coffee is part of the work day, watching Batman Returns probably isn’t
  • Try to set aside a specific place to work. This may or may not be possible for you - it helps but it isn’t essential.
  • Try to set a routine for when you start work or stop work (we have practical tips below). This may also not be possible for you, especially if there are children around the house. Be careful of your mental health here: do not set yourself a rigid routine you cannot follow, it is a very swift route to discouragement and depression.

How to Think (Manager Special)

There’s something critically important you must realise as a manager used to being in an office with your team: whether you mean to or not, you almost certainly judge people’s level of work by how much time they spend at their desk. It’s super hard not to!

In the section below, there’s specific tips on communication - but as a manager/team lead, be deliberate in judging how things are going by people’s status updates and the work they are producing, not by how quickly they answer your chat message. People shouldn’t be on hair-trigger chat response all day (unless that’s their actual job), so give them the space to concentrate and get on with work.

You will also have to think hard about how to help people break tasks down into chunks that you can see updates on on a daily basis. With a team inexperienced at remote working and an increasing chance of people needing to take personal or sick days, it’s important that as many pieces of work as possible are left in a “handoverable” state at the end of every working day.

It is crucial that you (as a manager/lead) take part in the remote working culture and feel its pain points. One of the reasons we believe remote working has been so successful at NoRedInk is having built remote managers (including VPs) into the company right from the beginning of its remote working history.

Practical Tips

This is probably the bit you’re here for: practical hints and tips from people who have been doing this for a while. All of these are suggestions, not rules, and some may not be possible for you at the moment. Some of them even contradict! Humans are different, so pick the options that work for you.

Looking after yourself

  • No one will be asking you if you want a coffee. Make sure you have water to hand, and set times to go and get a drink.
  • Be careful with snacks! Don’t leave food out (if you’re like me, if it is visible you will eat it)
  • It’s okay to have your pets around, especially if you live on your own.
    • If your cat wants to sit on your laptop you can always distract it with a hot water bottle in a blanket.
  • Make sure you do some exercise. You’d be surprised how active most people’s commutes are; you’ll need to be deliberate in doing something else to make up for it.
  • Be deliberate to physically move throughout the day. In the office, when a meeting starts or ends you get up and move around. At home, you plug in some headphones. If you find yourself sitting around for extended periods, set a timer to remind yourself to move.
  • Reach out to people frequently. There’s a section below on communication in general, but do not sit around at home feeling lonely: we’re aiming to be physically distant, but not emotionally/socially distant.
  • Video calls (especially one to one) can be very socially intense, even more so than in person meetings. If you are an introvert, try not to book multiple video calls back to back.
  • Your children are important, and they are dealing with a stressful unexpected change of circumstances. There will be times where they interrupt your work, have meltdowns, need a hug, or just will not sleep. Do what needs to be done for them, and decide in advance that you’re not going to feel guilty about it when it delays your work production (harder than it sounds).
    • Managers: please explicitly support this. You cannot believe how much of a difference it made to my mental health to start working in a remote environment where looking after the family was explicitly affirmed.

Communication (for Introverts and Extroverts)

  • If your job doesn't already have a strong remote culture, communicate until you feel like you're overcommunicating. (although that's true even if you do have a strong remote culture.)
  • Set up a shared document where each person tracks a high level list of what they’re working on for the day. Google Docs or Dropbox Paper are perfect for this.
  • Set up a text based chat channel for your team. Ask everyone to check it regularly during the day (maybe once per hour) so that your team can communicate without interrupting each other. It’s best not to set up alerts on this channel if you can avoid it.
    • Post anything in here; this is not a replacement for email, this is a replacement for “what did you do last weekend”
  • When using text chat, don’t get too fine grained. You might not get a reply for 30-60minutes, so don’t say “Hi Bob” and wait for a response. Post your actual question/information straight away.
  • Video chat is pretty good for face to face meetings these days: we use Zoom (https://zoom.us/) but most of the major providers are good. We do find Zoom copes better with large groups compared to the competitors we’ve tried.
  • If you end up doing this for the long haul, set up check-ins with coworkers. Like, literally put 15 or 30 minute meetings on their calendars where you just talk about life.
  • “I enjoy hopping on a zoom with colleagues even if we're not collaborating to feel like I'm in a community / to have the opportunity for office banter.”
  • Put together a “Social Contact Cheatsheet” for yourself, and share it (even better, have a directory for everyone who’s remoting).
    • It should have things like: preference order for contact methods (“i.e. email, then chat, then video”)
    • Your contact hours (see section below on choosing working hours)
    • Whether you like to be warned before voice/video contact (with the family around, people often need a moment to set up before accepting a call)
    • Let people know if you prefer to work mostly “alone”, in a shared social channel (i.e. group video call of people hanging out but not directly collaborating) or to actively pair work with a team member
  • Managers: It is much, much easier to build a good remote working communication environment if the whole team/department/company is remote working. If there are groups of people staying office based, make sure that you insist they take part in the remote communication channels or you will lose things between the gaps.

Processes/Routine

  • If possible, power down all your work stuff at the end of your day and leave it that way / put it away.
  • Create a personal routine, let people know when it affects the wider team
  • “When I close my computer at 5:30pm it's done. Slack goes DND on my phone, emails are turned off etc. The way I work isn't location based (I have 3-4 different spots around the house where I camp out) but strongly time-based.”
  • Take care with social media! At home, there’s no external time constraints to how long you spend browsing it, so it’s easy to spend much longer on it than you mean to.
  • Be realistic in the routines you set; you may have to adjust timings significantly from “normal” to work around constraints at home.
  • Managers: now is not a good time to insist on 9-5 working. If there are on call requirements, work out with your team who is covering when - but now is a good time to ditch “core office hours”.

Working Environment

Free Probabilities

As the Monty Python crew would say: "Now for something completely different!"

TL;DR: I'm going to turn a Monad of probabilities into a Free Monad of probabilities and this is not nearly so scary as it sounds. Also, it's actually useful!

I've been using a bit more Haskell recently, and after watching a demo from a colleague I wanted to solve a problem that's been bouncing around my brain for a while.

I do a fair bit of both game playing and game design (in the board game and tabletop roleplaying sense of 'game'), and I'm often interested in either generating random values or investigating how likely the result of a random process is.

Let's give an example; if I model a dice roll with the "spread" of possible outcomes, it might look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{-# LANGUAGE DeriveFunctor #-}

import Protolude
import Data.Ratio

type Probability = Ratio Integer

newtype Spread a =
  Spread [(a, Probability)]
  deriving (Show, Eq, Functor)

dice :: Spread Integer
dice = Spread [(1, 1 % 6)
              ,(2, 1 % 6)
              ,(3, 1 % 6)
              ,(4, 1 % 6)
              ,(5, 1 % 6)
              ,(6, 1 % 6)
              ]

Shake: Generated Files

This post is part of a series! If you haven't already, check out the introduction so you know what's going on.

It's fairly obvious how dependencies work in Shake when all of the files are known while you're writing your rules.

And if a build rule creates a single file matching a pattern, or even a known set of files based on a pattern: that's pretty simple too. Just add a rule (%> for building a single file, &%> for a list) and then when you need one of the outputs Shake knows how to make sure it's up to date.

Life becomes a little more interesting when you have a rule that takes multiple inputs (detected at run time) and creates multiple outputs (depending on what was found).

Let's look at an example. We're writing a computer game, and the game designers want to be able to quickly specify new types of characters that can exist. The designers and developers settle on a compromise; they'll use Yaml with a few simple type names the developers will teach the designers.

So the designers start churning out character types, which look like this:

1
2
3
name: Fighter
insaneToughness: Integer
ridiculousStrength: Integer

or this:

1
2
name: Rogue
sneakyTricks: "[String]"

The developers, on the other hand, want to be able to consume nice safe Haskell types like so:

1
2
3
4
5
6
7
8
9
10
11
12
import Generated.Fighter
import Names

main :: IO ()
main = do
  putStrLn $ "Hello, " ++ world ++ "!"
  print
    ( Fighter
      { insaneToughness = 5
      , ridiculousStrength = 10
      }
    )

And we want our code to break at compile time if, for any reason, the Yaml files get changed and we start relying on things that no longer exist. So we're going to set up a build rule that builds a directory full of nice type safe code from a directory full of nice concise and easy to edit Yaml.

Shake: Linting and Formatting

This post is part of a series! If you haven't already, check out the introduction so you know what's going on.

There's a bunch of nice tools out there these days that operate on your source code itself, such as auto-formatting and linting tools.

How to configure rules for this kind of thing in Shake isn't immediately obvious when you're new to using it. The first time I did it, I ended up with something that looked like this (only showing relevant rules):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  "_build" </> "main" <.> exe %> \out -> do
    src <- getDirectoryFiles "" ["src//*.hs"]
    cmd_
      "hlint"
      src
    need src
    cmd_
      "ghc"
      ("src" </> "main.hs")
      "-isrc"
      "-outputdir"
      "_build"
      "-o"
      out

Which at first glance looks great! I've made sure that I find and run hlint (a Haskell linting tool) on the source files before I "need" them - remember, once a file has been "needed" in Shake it should not be changed. The code is simple and easy to read. hlint gets efficiently run on the whole list of source files all at once.

What's not to like?

Shake: The Intro

At NoRedInk we've been looking into using Shake to incrementally build large polyglot projects. In general, it's been a great tool to work with, but there were a few things that caught us out, so I wanted to capture some of that learning before it got lost.

Shake is basically a domain specific language built on top of Haskell, so knowing Haskell can definitely help you unlock it's full power. But you can get a long way for basic builds by just working with some simple building blocks. You will have to jump through some extra hoops to get it installed and write your scripts with editor support if you're not using Haskell anyway - but we are, so that wasn't much of an obstacle for us!

I'm not going to go into the really basic ideas behind Shake: the main website (linked above) has a good introductory demo, and Neil Mitchell (who wrote Shake) has given numerous (very well done) talks on the ideas behind it. What I'm going to do over a few posts is look at some of the things which caught us out, and what you can do about them. I'll try and remember to link each post here as it comes out!

Property Based Testing at NDC Oslo 2018

This summer I spoke at NDC Oslo. It's a fantastic event (if huge!), with good talks but also excellent facilities and shared spaces for meeting up with people.

Over the last few weeks, they've been publishing the videos of this year's talks, and mine appeared without me noticing. If you're interested in a deep dive session on using property based testing to test a templating library, you might find this interesting…

You can find all of the example code on GitHub: https://github.com/mavnn/ndcoslo2018

Working With NoRedInk

It's all change here at @mavnn land: as of last week, we've signed a full time, indefinite contract with NoRedInk to provide development services.

Given that we're a two person company, and only one of us is a developer, that means we won't be taking on any other work for the foreseeable future!

So, what's going on, why, and what does it mean for you?

Why?

The reasons come on a few levels, but they basically boil down to:

  • I think NoRedInk are doing something really worthwhile, and they really understand remote teams
  • My family may need to move on fairly short notice at some point (cough Brexit cough) and neither on-site work nor short term contracts give much security in that context

There are other reasons, and not necessarily minor ones:

  • They have an in-depth interview process which has convinced me I can work with the engineers there
  • They're using Elm on the front end, which I really like the look of
  • They're investing in tooling and support

I'm only just getting started with them (last week they had a 3 day retreat I was able to join them for, this week I'm at NDC Oslo), but so far I can tell you that they seem to be a great bunch of human beings with a clear, concrete, targeted plan on how to make (one aspect of) the world better. I can get behind that.

What does it mean for you?

Well, basically it means that @mavnn ltd will no longer be running on site training or ticketed training events, and we won't be available for bespoke development. It also means that I'll be a lot less active in the F# community; I have 3 new programming languages to learn and become productive with in fairly short order.

Having said that, you can probably expect some cross-ecosystem pollination talks at conferences in the future!

Anyway: enough about me. I now return you to your regular schedule of techy bloginess.

Full Stack With Freya

Yesterday night I was about to demo a quick server/client pair with Freya and Fable, and it all went a bit wrong. Some of the issues weren't related to what I did (computers, gotta love 'em) but others were just bits of configuration that I didn't have at my finger tips.

This means it's time for a little practice for me, and a mini-tutorial for you (and future me).

RouteMaster and the Tale of the Globally Unique Voters

RouteMaster is a process manager library I've been working on for simplifying the creation of complex work flows in message based systems.

One of the challenges RouteMaster faces is that once you have defined your "route" in RouteMaster, you generally want to run multiple instances of your process manager service in your distributed environment. This means that a lot of care has been taken to make sure that things like work flow state is handled safely, but it also causes a particular challenge for dealing with timeouts.

Cloud Native .NET

We're launching a new two day course this April (26th/27th), called "Cloud Native .NET". Despite the slightly pretentious name the industry has come up with, what we're really talking about here are the core engineering skills of building code that can be scaled and maintained. This course is a practical workshop using .NET Core and Kuberenetes so we can see what it all looks like in practice.

Full details below!