Small Libraries

28.11.2013

Go'Circuit

feedback := make(chan int)
circuit.Spawn("host25.datacenter.net", func() {
    feedback <- 1
})
<-feedback
println("Roundtrip complete.")

Circuit

Circuit Runtime

import _ "circuit/load/cmd"
import "circuit/use/circuit"

Spawning a worker

Spawn(host circuit.Host, anchor []string, f circuit.Func, in ...interface{})
    (out []interface{}, addr circuit.Addr, err error)

Worker functions

import "circuit/use/circuit"

type MyWorkerFunc struct{}

func (MyWorkerFunc) SingletonMethod(greeting string) (response string) {
    return "Hello " + greeting
}

func init() {
    circuit.RegisterFunc(MyWorkerFunc{})
}

Spawn semantics

Daemonizing worker functions

import "circuit/use/circuit"

type StartServer struct{}

func (StartServer) Main() (hostport string, err error) {
    server, err := StartLocalWebServer()   // Bind a web server
    if err != nil {
        return "", err
    }
    go func() {                            // Start accepting requests in new goroutine
        for { server.AcceptNext() }
    }()
    return server.HostPort(), nil          // Communicate the URL of the server to the caller
}

func init() {
    circuit.RegisterFunc(StartServer{})
}

Daemonizing worker functions (fixed)

...
circuit.RunInBack(func() {
    for { server.AcceptNext() }
})
...

Communicating across workers

Cross-interfaces

Making cross-interfaces

func (fs *FileSystem) Open(name string) (*File, error) {
    …
    return file, nil
}
func (fs *FileSystem) Open(name string) (circuit.X, error) {
    …
    return circuit.Ref(file), nil
}

Using cross-interfaces

Call(proc string, in ...interface{}) []interface{}

Cross-runtime garbage collection

Transmitting data structures

encoding/gob

gob!?

Binary values exchanged between an Encoder (transmitter) and a Decoder (receiver)

gob стойности

Ако изпратим:

type T struct{ X, Y, Z int }
var t = T{X: 7, Y: 0, Z: 8}

Можем да ги получим като:

type U struct{ X, Y *int8 }

Какво точно се праща по мрежата

("define type id" 127, definition of type T)(127, T value)(127, T value), ...

Какво правим, ако решим да си говорим с нещо различно от go?

Очевидно ще си говорим за json от тук нататък.

Marshalling

The process of transforming the memory representation of an object to a data format suitable for storage or transmission

Някои му викат сериализация

Example

package main

import (
	"encoding/json"
	"fmt"
	"os"
)

func main() {
    type ColorGroup struct {
        ID     int `asdasdsad:",string"`
        Name   string
        Colors []string
    }
    group := ColorGroup{
        Name:   "Reds",
        Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
    }
    b, err := json.Marshal(group)
    if err != nil {
        fmt.Println("error:", err)
    }
    os.Stdout.Write(b)
}

Pros and Cons

Pros:

Cons:

Field tags

На всяка стойност в strcut можем да прилагаме тагове за конкретен формат.

Field int `json:"-"` // Няма да бъде сериализрано
Field int `json:"myName,string"` // Ще бъде сериализрано като myName от тип string
Field int `json:",omitempty"` // Няма да бъде сериализирано, ако е празно

Unmarshal

Очевидно ако получим вече сериализиран json, можем да го десериализираме.

bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null

And now for something completely different

unsafe

Пакет, в стандартната библиотека, който съдържа няколко операции, заобикалящи type safety-то на езика.
Нямаме особено добра идея защо са ви...

sync/atomic

Съдържа примитиви от ниско ниво за разни операции, които сме сигурни, че са атомарни.

Функцията CompareAndSwapT е аналогична на:

if *addr == old {
    *addr = new
    return true
}
return false

Въпроси?