Go Heartbeat: Difference between revisions
Jump to navigation
Jump to search
(Created page with "=Internal= * Go Concurrency =Overview=") |
|||
(4 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=External= | |||
* Concurrency in Go Katherine Cox-Buday, Chapter 5. "Concurrency at Scale" Section "Heartbeats" | |||
=Internal= | =Internal= | ||
* [[Go_Concurrency#Concurrency_Patterns|Go Concurrency]] | * [[Go_Concurrency#Concurrency_Patterns|Go Concurrency]] | ||
=Overview= | =Overview= | ||
Heartbeats are a way for concurrent processes to signal life to outside parties. | |||
There are two different types of heartbeats: that occur on a time interval, and that occur at the beginning of a unit of work. | |||
=Example= | |||
<syntaxhighlight lang='go'> | |||
// makeHeartbeatChannel will start a goroutine that sends heartbeats with the given duration on the channel | |||
// returned as result. The heartbeat will be canceled when the context is canceled. When the heartbeat is | |||
// canceled, the returned channel will be closed. | |||
func makeHeartbeatChannel(ctx context.Context, interval time.Duration) <-chan interface{} { | |||
c := make(chan interface{}) | |||
ticker := time.NewTicker(interval) | |||
sendHeartbeat := func() { | |||
select { | |||
case c <- struct{}{}: | |||
default: | |||
// if the channel is blocked, give up, we'll send heartbeat next time | |||
} | |||
} | |||
go func() { | |||
defer close(c) // we own the channel, we must close it when it's not needed anymore | |||
defer ticker.Stop() | |||
for { | |||
select { | |||
case <-ctx.Done(): | |||
fmt.Println("context canceled") | |||
return | |||
case <-ticker.C: | |||
sendHeartbeat() | |||
} | |||
} | |||
}() | |||
return c | |||
} | |||
... | |||
ctx, cancel := context.WithCancel(context.Background()) | |||
heartbeat := makeHeartbeatChannel(ctx, 1*time.Second) | |||
go func() { | |||
<-time.After(10 * time.Second) | |||
cancel() | |||
}() | |||
for { | |||
select { | |||
case _, ok := <-heartbeat: | |||
if ok == false { | |||
return | |||
} | |||
fmt.Println(".") | |||
} | |||
} | |||
</syntaxhighlight> |
Latest revision as of 21:19, 13 February 2024
External
- Concurrency in Go Katherine Cox-Buday, Chapter 5. "Concurrency at Scale" Section "Heartbeats"
Internal
Overview
Heartbeats are a way for concurrent processes to signal life to outside parties.
There are two different types of heartbeats: that occur on a time interval, and that occur at the beginning of a unit of work.
Example
// makeHeartbeatChannel will start a goroutine that sends heartbeats with the given duration on the channel
// returned as result. The heartbeat will be canceled when the context is canceled. When the heartbeat is
// canceled, the returned channel will be closed.
func makeHeartbeatChannel(ctx context.Context, interval time.Duration) <-chan interface{} {
c := make(chan interface{})
ticker := time.NewTicker(interval)
sendHeartbeat := func() {
select {
case c <- struct{}{}:
default:
// if the channel is blocked, give up, we'll send heartbeat next time
}
}
go func() {
defer close(c) // we own the channel, we must close it when it's not needed anymore
defer ticker.Stop()
for {
select {
case <-ctx.Done():
fmt.Println("context canceled")
return
case <-ticker.C:
sendHeartbeat()
}
}
}()
return c
}
...
ctx, cancel := context.WithCancel(context.Background())
heartbeat := makeHeartbeatChannel(ctx, 1*time.Second)
go func() {
<-time.After(10 * time.Second)
cancel()
}()
for {
select {
case _, ok := <-heartbeat:
if ok == false {
return
}
fmt.Println(".")
}
}