Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Go: A Language Built for Getting Things Done

Go: A Language Built for Getting Things Done

I’m the platform tech lead for the content platform at the Financial Times. We’re building this platform using a microservices architecture. Over the last year, we’ve moved from Java to Go as our default language.

So what led a group of experienced Java programmers to make this jump? Go is an efficient, scalable and productive language that’s also just a little bit boring. Its creators describe it as “a language for programmers who want to get things done.” Our experience is that it’s ideally suited for building simple microservices that communicate using json over http. Read this talk and find out more, including how easy it is to write your first microservice in Go.

A288fb976fc633cde90a2bc19bf2b5a6?s=128

Sarah Wells

October 27, 2016
Tweet

Transcript

  1. Go: a language built for getting things done Sarah Wells

    Principal Engineer, Financial Times @sarahjwells
  2. @sarahjwells Hello

  3. @sarahjwells Building a microservices architecture

  4. @sarahjwells Running applications in containers

  5. @sarahjwells The JVM makes docker images bigger

  6. @sarahjwells Image size container memory used vs

  7. @sarahjwells Enthusiastic gopher on the team!

  8. @sarahjwells About Go Robert Griesemer, Rob Pike, and Ken Thompson

  9. @sarahjwells “Efficient, scalable and productive”

  10. @sarahjwells • Started Sept 2007 • Announced and open sourced

    in Nov 2009 • Go 1.0 released March 2012 • Now on version 1.7 (released 2016/08/15) • Both 1.6 and 1.7 releases were mostly changes in the implementation of the toolchain, runtime, and libraries
  11. @sarahjwells Built to solve Google’s problems

  12. @sarahjwells – Rob Pike keynote at SPLASH 2012 conference “to

    eliminate the slowness and clumsiness of software development at Google, and thereby to make the process more productive and scalable”
  13. @sarahjwells Can’t be too radical, need developers to be productive

    quickly
  14. @sarahjwells Must cope with the modern world: multicore machines, web

    applications
  15. @sarahjwells Must work at scale: large programmes, lots of developers

    working on them
  16. @sarahjwells Designed to make tools easy to write

  17. @sarahjwells Getting started with Go

  18. @sarahjwells • https://golang.org/ • Install Go • Create a workspace

    directory, e.g. go-workspace • set $GOPATH to point to that workspace
  19. @sarahjwells package main import ( "fmt" "github.com/golang/example/stringutil" ) func main()

    { fmt.Println(stringutil.Reverse("Hello world")) }
  20. @sarahjwells package main import ( "fmt" "github.com/golang/example/stringutil" ) func main()

    { fmt.Println(stringutil.Reverse("Hello world")) }
  21. @sarahjwells package main import ( "fmt" "github.com/golang/example/stringutil" ) func main()

    { fmt.Println(stringutil.Reverse("Hello world")) }
  22. @sarahjwells package main import ( "fmt" "github.com/golang/example/stringutil" ) func main()

    { fmt.Println(stringutil.Reverse("Hello world")) }
  23. None
  24. @sarahjwells package main import ( "fmt" "github.com/golang/example/stringutil" ) func main()

    { fmt.Println(stringutil.Reverse("Hello world")) }
  25. @sarahjwells Go tooling

  26. @sarahjwells go fmt - formats your code according to specific

    rules • Easier to write • Easier to read • Easier to maintain • Fewer arguments!
  27. @sarahjwells Allows you to easily do automatic code transformations

  28. @sarahjwells FT-MW4708:wosr sarah.wells$ go help Go is a tool for

    managing Go source code. Usage: go command [arguments] The commands are: build compile packages and dependencies clean remove object files doc show documentation for package or symbol env print Go environment information fix run go tool fix on packages fmt run gofmt on package sources
  29. @sarahjwells … generate generate Go files by processing source get

    download and install packages and dependencies install compile and install packages and dependencies list list packages run compile and run Go program test test packages tool run specified go tool version print Go version vet run go tool vet on packages
  30. @sarahjwells Go workspace

  31. None
  32. go get github.com/golang/example/hello

  33. @sarahjwells Let’s have a look at some more code

  34. @sarahjwells Functions

  35. @sarahjwells func split(sum int) (x, y int) { x =

    sum * 4 / 9 y = sum - x return } func main() { x, y := split(15) fmt.Printf("x=%d, y=%d\n", x, y) //outputs x=6, y=9 }
  36. @sarahjwells func split(sum int) (x, y int) { x =

    sum * 4 / 9 y = sum - x return } func main() { x, y := split(15) fmt.Printf("x=%d, y=%d\n", x, y) //outputs x=6, y=9 }
  37. @sarahjwells Error handling

  38. @sarahjwells type error interface { Error() string }

  39. @sarahjwells package os func Open(name string) (file *File, err error)

    … f, err := os.Open("filename.ext") if err != nil { log.Fatal(err) } // do something with the open *File f
  40. @sarahjwells Objects

  41. @sarahjwells type Rect struct { width int height int }

    func (r Rect) Area() int { return r.width * r.height } func main() { r := Rect{width: 10, height: 5} fmt.Printf("area: %d\n", r.area()) }
  42. @sarahjwells type Rectangle struct { width int height int }

    func (r Rectangle) Area() int { return r.width * r.height } func main() { r := Rectangle{width: 10, height: 5} fmt.Printf("area: %d\n", r.Area()) }
  43. @sarahjwells Interfaces

  44. @sarahjwells type Writer interface { Write(p []byte) (n int, err

    error) }
  45. @sarahjwells package os func (f *File) Write(b []byte) (n int,

    err error) { if f == nil { return 0, ErrInvalid } … }
  46. @sarahjwells type ByteCounter struct { counter int } func (c

    *ByteCounter) Write(p []byte) (int, error) { (*c).counter += len(p) return len(p), nil }
  47. @sarahjwells package fmt // writes to the supplied writer func

    Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { p := newPrinter() p.doPrintf(format, a) n, err = w.Write(p.buf) p.free() return }
  48. @sarahjwells Concurrency

  49. @sarahjwells func main() { fmt.Printf("Hello\n") go slowFunction() fmt.Printf("Bye!\n") } func

    slowFunction() { //do something slow time.Sleep(1 * time.Second) fmt.Printf("Finished slow stuff\n") }
  50. @sarahjwells ch := make(chan int) ch <- v // Send

    v to channel ch. v := <-ch // Receive from ch, and // assign value to v.
  51. @sarahjwells func main() { rand.Seed(time.Now().UnixNano()) responses := make(chan string, 5)

    for i := 1; i <= 5; i++ { go slowFunction(i, responses) } fmt.Printf("Winner was %s\n", <-responses) } func slowFunction(num int, out chan<- string) { waitSeconds := rand.Intn(10) fmt.Printf("Num %d is waiting %d seconds\n", num, waitSeconds) time.Sleep(time.Duration(waitSeconds) * time.Second) out <- fmt.Sprintf("%d", num) }
  52. @sarahjwells func main() { rand.Seed(time.Now().UnixNano()) responses := make(chan string, 5)

    for i := 1; i <= 5; i++ { go slowFunction(i, responses) } fmt.Printf("Winner was %s\n", <-responses) } func slowFunction(num int, out chan<- string) { waitSeconds := rand.Intn(10) fmt.Printf("Num %d is waiting %d seconds\n", num, waitSeconds) time.Sleep(time.Duration(waitSeconds) * time.Second) out <- fmt.Sprintf("%d", num) }
  53. @sarahjwells func main() { rand.Seed(time.Now().UnixNano()) responses := make(chan string, 5)

    for i := 1; i <= 5; i++ { go slowFunction(i, responses) } fmt.Printf("Winner was %s\n", <-responses) } func slowFunction(num int, out chan<- string) { waitSeconds := rand.Intn(10) fmt.Printf("Num %d is waiting %d seconds\n", num, waitSeconds) time.Sleep(time.Duration(waitSeconds) * time.Second) out <- fmt.Sprintf("%d", num) }
  54. @sarahjwells That webservice…

  55. @sarahjwells func main() { ah := authorHandler{newHardCodedAuthorService()} r := mux.NewRouter()

    r.HandleFunc("/authors/{uuid}", ah.getAuthor).Methods("GET") http.Handle("/", r) log.Fatal(http.ListenAndServe("localhost:8000", nil)) } type authorHandler struct { as authorService }
  56. @sarahjwells func main() { ah := authorHandler{newHardCodedAuthorService()} r := mux.NewRouter()

    r.HandleFunc("/authors/{uuid}", ah.getAuthor).Methods("GET") http.Handle("/", r) log.Fatal(http.ListenAndServe("localhost:8000", nil)) } type authorHandler struct { as authorService }
  57. @sarahjwells func (ah *authorHandler) getAuthor(writer http.ResponseWriter, req *http.Request) { vars

    := mux.Vars(req) uuid := vars["uuid"] requestedAuthor, found := ah.as.getAuthorByUUID(uuid) if !found { writer.WriteHeader(http.StatusNotFound) return } enc := json.NewEncoder(writer) //should have error handling here enc.Encode(requestedAuthor) }
  58. @sarahjwells type authorService interface { getAuthorByUUID(uuid string) (author, bool) }

    type simpleAuthorService struct { authors map[string]author } func (as simpleAuthorService) getAuthorByUUID(uuid string) (author, bool) { requestedAuthor, found := as.authors[uuid] return requestedAuthor, found }
  59. @sarahjwells type author struct { Name string `json:"name"` Email string

    `json:"email"` ImageURL string `json:"imageurl"` Biography string `json:"biography"` TwitterHandle string `json:"twitterhandle"` TmeIdentifier string `json:"tmeidentifier"` }
  60. @sarahjwells Summary

  61. @sarahjwells We’ve talked about: • the language aims • tooling

    • some of the interesting design decisions
  62. @sarahjwells So who’s using Go? • Docker is written in

    Go • Dropbox use Go (as well as Python) • Netflix rewrote their chaos monkey in Go
  63. @sarahjwells Resources

  64. @sarahjwells • https://golang.org - the home of Go, including go

    docs • Start with the Go tour: https://tour.golang.org/welcome/1 • Then Effective Go: https://golang.org/doc/effective_go.html • Go by Example: https://gobyexample.com/
  65. @sarahjwells http://www.gopl.io/ https://github.com/adonovan/ gopl.io

  66. @sarahjwells Code samples: https://github.com/sjwells/wosr

  67. @sarahjwells Thank you!