Skip to content

Instantly share code, notes, and snippets.


Steve Coffman StevenACoffman

  • Khan Academy
  • Ann Arbor, MI
View GitHub Profile

Change jobs every two to three years.

  • The Carrot

    The worst kept secret is that employees are making less on average every year. There are millions of reasons for this, but we’re going to focus on one that we can control. Staying employed at the same company for over two years on average is going to make you earn less over 10 years by about 50% or more.

    Keep in mind that 50% is a conservative number at the lowest end of the spectrum. The longer you work, the greater the difference will become over your lifetime.

StevenACoffman / main.go
Created May 19, 2021 — forked from salrashid123/main.go
Sample golang app that uses the Google CLoud Admin SDk to create a user and then add that user to a specific google group
View main.go
package main
import (
View Watermill and

Temporal and Watermill solve different problems, or solve problems differently. From a domain perspective, Temporal workflows implement policies and as a result they provide orchestration for the entire process. Nothing stops you from implementing workflows that span through different domains (bounded contexts) though, so if the process is well defined, you can implement it in a single workflow. That gives you the advantage of being able to remediate if any of the steps fail (eg. if the payment fails, the order shouldn't be sent to shipping).

That's not always the case though. Sometimes you need to provide integration points in the system that lets actors outside of a business process to react to events which is when Watermill comes into the picture.

Ultimately, the two can be combined very easily. For example, a Temporal activity can send an event to watermill, or a watermill event can start a new workflow.

As a rule


This is my notes from a few articles:

Some error values are mostly just used for control flow. For example, "Access Denied", or "Authentication Required".

In my opinion, you should only add stack trace to an error which is potentially going to break your program. A logical error like we have seen in the authorization example does not need a track state. But since Wrap method can be used to ammend original error message which is also called as annotating an error, the choice is up to you.

The types of errors that would bubble up to be a 500 Internal Server Error generally require investigation by a developer. In these cases, a stacktrace (and ideally other contextual information) is incredibly valuable.

StevenACoffman /
Created Dec 17, 2020 — forked from parmentf/
Git Commit message Emoji

You can think loosely of channels like pipes for fluid - pour it in one end and out at the other.

By including the arrow <- chan or chan <-, you are achieving three things:

  1. You are making it clear that the parameter is one end of a channel.
  2. You are expressing clearly which end is being supplied.
  3. You are giving more information to the compiler for checking. If the function body tries to use the wrong end of the channel, the compiler can raise an error. These are good reasons to show the channel end whenever possible.

| when you see | which end is of the channel is it for? |

StevenACoffman / gvn.go
Last active Sep 10, 2020
Retrieve App Engine Version name from local git information in Pure JavaScript or in Pure Go
View gvn.go
package main
import (

Hi Steve,

You go to APIs and Services > Credentials in the console and you can either take one of the keys that are already there or you can create a new one with the "Create Credentials" button. This is the only way to create API keys, but they can be reused any amount of times. There is a feature request to create them with a gcloud command, however. You can follow it here if you're interested.

Let me know if you have any other questions or concerns and I'll be happy to help.