Full Stack Go, Part 2: Web & Native Desktop/Mobile

Recurse Center

25 March 2015

Aditya Mukerjee

Full Stack Go, Part 1: Servers (Recap)

What did we learn?

A bit more on concurrency

Synchronicity by Example

func Greet(name string) {
    log.Printf("Greetings, %s!", name)
    time.Sleep(3 * time.Second)
}

func main() {
    Greet("Alice")
    Greet("Bob")
}

Goroutines by Example

func Greet(name string) {
    log.Printf("Greetings, %s!", name)
    time.Sleep(3 * time.Second)
}

func main() {
    go Greet("Alice")
    go Greet("Bob")

    time.Sleep(5 * time.Second)
}

Yes, it really is just that easy.

Goroutines vs. Callbacks

func getPersonAge(name) int {
    // Is there a drop-in asynchronous replacement for
    // synchronous http.Get using only callbacks?
    result = http.Get("https://api.example.com/person" + name)
    return unmarshal(result).Age
}

Concurrency in Go: Channels

Channels by Example:

func Greet(name string, response_chan chan string) {
    greeting := fmt.Sprintf("Greetings, %s!", name)
    response_chan <- greeting
}

func main() {

    cs := make(chan string)
    go Greet("Alice", cs)
    greeting := <-cs
    log.Print(greeting)
}

Let's take a closer look at that:

func Greet(name string, response_chan chan string) {
    time.Sleep(3 * time.Second)
    greeting := fmt.Sprintf("Greetings, %s!", name)
    response_chan <- greeting
    log.Print("Greeting function is tired - sleeping for a bit")
    time.Sleep(3 * time.Second)
    log.Print("now the greeting function is done sleeping - terminating")
}

func main() {

    cs := make(chan string)
    go Greet("Alice", cs)
    log.Print("Continuing execution while we wait for greeter to respond")
    greeting := <-cs
    log.Print(greeting)
    time.Sleep(10 * time.Second)
}

Selecting Channels

select {
    case <-algorithm1:
        // algorithm1 was faster
    case <-algorithm2:
        // algorithm2 was faster
}
select {
    case <-ch:
        // a read from ch has occurred
    case <-timeout:
        // the read from ch has timed out
}

But why can't I just use <insert Javascript pattern here/>?

Pre-emption vs. cooperation

(†Obligatory "well actually": inlined functions do not invoke the scheduler, but gc is very non-aggressive with inlining)
‡ If you solve this challenge, don't tell anyone else, but tell me so we can write the paper together and make lots of $$$

In conclusion: Go makes concurrency easy

Why is this relevant to full-stack Go?

Client-Side Go: Android

History of Go on Android

Basic example: Framerate test

github.com/golang/mobile/tree/master/example/basic

Screenshots

What about iOS?

Client-Side Go: Web

Examples

Client-Side Go: FirefoxOS

Wait, isn't that cheating?

Client-Side Go: Native Desktop Applications

Client-Side Go: Native Desktop Applications (approach #2)

Key Takeaways

Thank you

Aditya Mukerjee