Go for Rubyists

39
GO FOR RUBYISTS? Luka Zakraj š ek CTO @ Koofr @bancek Slovenia Ruby User Group, January Meetup January 29, 2015

Transcript of Go for Rubyists

GO FOR RUBYISTS?

Luka Zakrajšek

CTO @ Koofr

@bancek

Slovenia Ruby User Group, January Meetup

January 29, 2015

ABOUT MEFRI graduateCTO and cofounder at Koofr

Python developer in previous lifenow mostly Scala, Go and JavaScript

GO @ KOOFRKoofr is white-label cloud storage solution for ISPs

backendcontent server (downloads, uploads, streaming ...)FTP server...

desktop applicationGUI applicationsyncremote filesystem access

WHAT IS GOnew programming language from Googlelow levelC-like syntaxfast compilation (for large codebases)compiles to single binarycross platform (Windows, Linux, Mac)

WHAT IS GOstatically-typedmanaged memory (garbage collection)type safetydynamic-typing capabilitiesbuilt-in types (variable-length arrays and key-value maps)large standard library

GO IS C#include <stdio.h> main(){ printf("Hello World\n"); return 0;}

package main

import "fmt"

func main() { fmt.Println("Hello World")}

GO IS PYTHONimport reimport osimport Imageimport csvimport jsonimport gzipimport urllibimport unittest

import ( "regexp" "os.exec" "image/jpeg" "encoding/csv" "encoding/json" "compress/gzip" "net/http" "testing")

import "github.com/koofr/go-koofrclient"

GO IS NODE.JSvar http = require('http');http.createServer(function (req, res) { res.writeHead(200); res.end('Hello World');}).listen(1337, '127.0.0.1');console.log('Server running at http://127.0.0.1:1337/');

package mainimport ( "fmt" "net/http")func main() { http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World") }) http.ListenAndServe(":1337", nil) fmt.Println("Server running at http://127.0.0.1:1337/");}

GO FOR RUBYISTS

EASY AND CHEAP CONCURRENCYeasy to have dozens (or even thousands) of concurrentoperations

it will even take advantage of all the CPUs available

Ruby has threads, but there is GIL in Ruby MRI

Ruby has green threads, but will use single CPU

LOW MEMORY OVERHEADGo programs can be compiled to a few megabytes binary

memory efficient while harvesting the power of the entiremachine

EASY DEPLOYMENTGo programs are compiled in a few seconds into smallexecutables

no dependencies in production

USE GO FROM RUBYGo:

package main import "fmt"import "encoding/json" func main() { mapD := map[string]int{"apple": 5, "lettuce": 7} mapB, _ := json.Marshal(mapD) fmt.Println(string(mapB))}

Ruby:JSON.parse(go run json.go)# => {"apple"=>5, "lettuce"=>7}

https://antoine.finkelstein.fr/go-in-ruby/

BASIC CONSTRUCTS

PACKAGESlibraries structured in packagesprograms start running in package main

IMPORTSlocal imports (GOPATH env. variable)import directly from web (http, git, mercurial)capitalized identifiers are exported

import ( "fmt" "github.com/koofr/go-koofrclient")

FUNCTIONStake zero or more argumentsa function can return any number of results.types come after variable namesnamed return values

func myfunction(x, y int) (x int, y int) { tmp := x x = y y = tmp return // return y, x}

VARIABLESvar statement declares a list of variablestype comes after name

var c, python, java bool

func main() { var i int fmt.Println(i, c, python, java)}

short variable declarations

func main() { var i int = 1 k := 3 // type inference}

BASIC TYPESboolstringint, uint, int8, uint, int16, uint16, int32, uint32, int64, uint64,uintptrbyte // alias for uint8rune // alias for int32, represents a Unicode code pointfloat32, float64complex64, complex128

OTHER CONSTRUCTSpointersstructsarraysslicesmaps

INTERFACEStype Reader interface { Read(p []byte) (n int, err error)}

INTERFACEStype SizeReader struct { r io.Reader size int64}func (sr *SizeReader) Read(p []byte) (n int, err error) { n, err = sr.r.Read(p) sr.size += int64(n) return}func consumeReader(r io.Reader) { // ...}func main() { var sr *SizeReader = &SizeReader{myFile, 0} consumeReader(sr) fmt.Println(sr.size)}

GOROUTINES AND CHANNELSfunc doSomethingExpensive() int { time.Sleep(10 * time.Second) return 42}

func doItAsync() { go doSomethingExpensive()}

func doItAsyncAndGetResult() <-chan int { ch := make(chan int, 1) go func() { ch <- doSomethingExpensive() }() return ch}

ERROR HANDLINGfunc copyFile(src string, dest string) (i64, error) { r, err := os.Open(src) if err != nil { return err } defer r.Close()

w, err := os.Create(dest) if err != nil { return err } defer w.Close()

bytesCopied, err = io.Copy(w, r)

return bytesCopied, err}

GO COMMAND// fetch dependenciesgo get

// run testsgo test

// build binarygo build

// format codego fmt

// check for errors in codego vet

CODE STRUCTURE

LIBRARY STRUCTURE.gitignoreLICENSEREADME.mdcache.gocache_test.go

APPLICATION STRUCTUREsrc/ github.com/ koofr/ go-ioutils myapp/ internallib/ lib.go main/ main.go config.go myapp.go

bin/ myapppkg/build/dist/

TESTINGpackage newmath

import "testing"

func TestSqrt(t *testing.T) { const in, out = 4, 2 if x := Sqrt(in); x != out { t.Errorf("Sqrt(%v) = %v, want %v", in, x, out) }}

$ go testok github.com/user/newmath 0.165s

DEPLOYMENTgo build -o bin/myapp src/myapp/main/main.go

scp bin/myapp myserver.com:myapp

ssh myserver.com 'supervisorctl restart myapp'

WEB FRAMEWORKS

MARTINIClassy web framework for Go

similar to Sinatra

FEATURESFlexible RoutingVery flexible and extremely DRY. Name parameters, stack handlers,inject the dependencies.

ComprehensiveComes with a great set of stock middleware:Logging, Recovery, Static file serving, Authentication, Routing and more!

Reuse Existing CodeFully compatible with Go's http.HandlerFunc interface.Leverage the many awesome open source web packages built in Go

MARTINI EXAMPLEpackage main

import "github.com/go-martini/martini"

func main() { m := martini.Classic()

m.Get("/", func() string { return "Hello world!" })

m.Get("/hello/:name", func(params martini.Params) string { return "Hello " + params["name"] })

m.Run()}

REVELA high-productivity web framework for the Go language.

similar to Rails

FEATURESHot Code ReloadEdit, save, and refresh.

Comprehensiverouting, parameter parsing, validation, session/flash,templating, caching, job running, a testing framework, internationalization ...

High PerformanceBuilt on top of the Go HTTP server, three to ten times as many requests as Rails

FRAMEWORK DESIGNSynchronousThe Go HTTP server runs each request in its own goroutine.Write simple callback-free code without guilt.

StatelessProvides primitives that keep the web tier stateless for predictable scaling.Session data in stored cookies, cache backed by a memcached cluster.

ModularComposable middleware called filters, which implement nearly allrequest-processing functionality

REVEL PROJECT STRUCTURE myapp App root app App sources controllers App controllers init.go Interceptor registration models App domain models routes Reverse routes (generated code) views Templates tests Test suites conf Configuration files app.conf Main configuration file routes Routes definition messages Message files public Public assets css CSS files js Javascript files images Image files

QUESTIONS?