geek joy
Français
25
Feb.
2016

This is the content of a talk given at Golang Montréal meetup on February 22nd 2016, at Google Montréal.

This is a high level introduction to different bridges that exist between Go and other languages. It is not meant to be exhaustive nor does it go very deep in each subject, but I hope it is at least entertaining.

4
Jan.
2016

Here they are:

func retry(attempts int, sleep time.Duration, callback func() error) (err error) {
    for i := 0; ; i++ {
        err = callback()
        if err == nil {
            return
        }

        if i >= (attempts - 1) {
            break
        }

        time.Sleep(sleep)

        log.Println("retrying after error:", err)
    }
    return fmt.Errorf("after %d attempts, last error: %s", attempts, err)
}

func retryDuring(duration time.Duration, sleep time.Duration, callback func() error) (err error) {
	t0 := time.Now()
	i := 0
    for {
		i++

        err = callback()
        if err == nil {
            return
        }

		delta := time.Now().Sub(t0)
        if delta > duration {
			return fmt.Errorf("after %d attempts (during %s), last error: %s", i, delta, err)
        }

        time.Sleep(sleep)

        log.Println("retrying after error:", err)
    }
}

Use like this:

		var signedContent []byte
		err := retry(5, 2*time.Second, func() (err error) {
			signedContent, err = signFile(unsignedFile, contents)
			return
		})
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 500)
			return
		}

I’ve seen some frameworks and libs to do that.. like retry-go and backoff. They’re both good, but a bit overkill for most simple tasks.

I feel it’s such a simple function that you’d rather dump in the project that needs it, tweak the delays and the logging mechanisms, and be done with it.

31
Dec.
2015

I have been working with goa for the past few days and I must admit I’ve been impressed.

You define your API in code, it generates your swagger.json file as well as plenty of boilerplate code for you. It distinguishes nicely what belongs to code generation and what belongs to your business logic.

One thing I was trying to do with the current version, was to stream files in and out (like a file server API).

Here is a sample controller streaming out some io.Reader content:

func (c *ArtifactController) Get(ctx *app.GetArtifactContext) error {
	file, size, err := storageClient.GetFile(ctx.ArtifactPath)
	if err != nil {
		ctx.Error("storageClient.GetFile", "err", err)
		return err
	}

	ctx.Header().Set("Content-Length", fmt.Sprintf("%d", size))
	ctx.WriteHeader(200)

	_, err = io.Copy(ctx, file)
	return err
}

Writing the header before running io.Copy() is the trick to make sure the goa controller understand that you’ve handled the request properly, and it doesn’t need to generate a 500 error.

22
Dec.
2015

Each new year brings its new blog platform. My previous platform was a Blogofile, but then I lost track of the build process and didn,t update it any more.

Hopefully, this Hugo blog, backed by an automatic pull from my Caddy Server will mean I can update more frequently.

22
Dec.
2015

I’m a full stack software developer, a passionate Go developer, did a lot of Python and still love it. I love playing the devops too.

I’m the father of 5 beautiful children and live on the South Shore of Montreal, Canada.

I currently work at Intel Security as a Data Scientist.

Thanks to pdevty for the design