A goroutine can send a result back to the main flow through a channel.

goroutine A goroutine runs a function concurrently, and a channel can make the handoff deterministic.

Goroutine Handoff

label
goroutine_handoff.go
Replay: real traced execution (multi-file project)
package main

import "fmt"

func main() {
	var label = "report"
	done := make(chan string)

	go func() {
		done <- "worker:" + label
	}()

	message := <-done
	fmt.Println("label=", label)
	fmt.Println("message=", message)
	fmt.Println("received=", true)
}
package main

import "fmt"

func main() {
	var label = "task"
	done := make(chan string)

	go func() {
		done <- "worker:" + label
	}()

	message := <-done
	fmt.Println("label=", label)
	fmt.Println("message=", message)
	fmt.Println("received=", true)
}
package main

import "fmt"

func main() {
	var label = "result"
	done := make(chan string)

	go func() {
		done <- "worker:" + label
	}()

	message := <-done
	fmt.Println("label=", label)
	fmt.Println("message=", message)
	fmt.Println("received=", true)
}
  1. label ← "report", done ← (chan string)(⟨addr A⟩)

    5func main() {6  var label→ "report" = "report" //@label="task", "result"7  done→ (chan string)(⟨addr A⟩) := make(chan string)89  go func() {10    done <- "worker:" + label11  }()1213  message := <-done(chan string)(⟨addr A⟩)14  fmt.Println("label=", label)
  2. func()

    9go func() {10  done(chan string)(⟨addr A⟩) <- "worker:" + label"report"11}()
  3. message ← "worker:report"

    13  message→ "worker:report" := <-done(chan string)(⟨addr A⟩)14  fmt.Println("label=", label"report")15  fmt.Println("message=", message"worker:report")16  fmt.Println("received=", true)17}
    outputlabel= report
    message= worker:report
    received= true
  1. label ← "task", done ← (chan string)(⟨addr A⟩)

    5func main() {6  var label→ "task" = "task"7  done→ (chan string)(⟨addr A⟩) := make(chan string)89  go func() {10    done <- "worker:" + label11  }()1213  message := <-done(chan string)(⟨addr A⟩)14  fmt.Println("label=", label)
  2. func()

    9go func() {10  done(chan string)(⟨addr A⟩) <- "worker:" + label"task"11}()
  3. message ← "worker:task"

    13  message→ "worker:task" := <-done(chan string)(⟨addr A⟩)14  fmt.Println("label=", label"task")15  fmt.Println("message=", message"worker:task")16  fmt.Println("received=", true)17}
    outputlabel= task
    message= worker:task
    received= true
  1. label ← "result", done ← (chan string)(⟨addr A⟩)

    5func main() {6  var label→ "result" = "result"7  done→ (chan string)(⟨addr A⟩) := make(chan string)89  go func() {10    done <- "worker:" + label11  }()1213  message := <-done(chan string)(⟨addr A⟩)14  fmt.Println("label=", label)
  2. func()

    9go func() {10  done(chan string)(⟨addr A⟩) <- "worker:" + label"result"11}()
  3. message ← "worker:result"

    13  message→ "worker:result" := <-done(chan string)(⟨addr A⟩)14  fmt.Println("label=", label"result")15  fmt.Println("message=", message"worker:result")16  fmt.Println("received=", true)17}
    outputlabel= result
    message= worker:result
    received= true