Go Heartbeat: Difference between revisions

From NovaOrdis Knowledge Base
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(".")
	}
}