blob: d452b340da9b655bcebf5175b55fcf2aa55c7eb8 [file] [log] [blame]
Tim Windelschmidt6d33a432025-02-04 14:34:25 +01001// Copyright The Monogon Project Authors.
Serge Bazanskic00318e2021-03-03 12:39:24 +01002// SPDX-License-Identifier: Apache-2.0
Serge Bazanskic00318e2021-03-03 12:39:24 +01003
Serge Bazanski68ca5ee2021-04-27 16:09:16 +02004package memory
Serge Bazanskic00318e2021-03-03 12:39:24 +01005
6import (
7 "context"
8 "fmt"
9 "net"
10 "time"
11)
12
13// NetworkStatus is example data that will be stored in a Value.
14type NetworkStatus struct {
15 ExternalAddress net.IP
Serge Bazanski68ca5ee2021-04-27 16:09:16 +020016 DefaultGateway net.IP
Serge Bazanskic00318e2021-03-03 12:39:24 +010017}
18
Serge Bazanskic00318e2021-03-03 12:39:24 +010019// NetworkService is a fake/example network service that is responsible for
20// communicating the newest information about a machine's network configuration
21// to consumers/watchers.
22type NetworkService struct {
Serge Bazanski37110c32023-03-01 13:57:27 +000023 Provider Value[NetworkStatus]
Serge Bazanskic00318e2021-03-03 12:39:24 +010024}
25
26// Run pretends to execute the network service's main logic loop, in which it
27// pretends to have received an IP address over DHCP, and communicates that to
28// consumers/watchers.
29func (s *NetworkService) Run(ctx context.Context) {
30 s.Provider.Set(NetworkStatus{
31 ExternalAddress: nil,
Serge Bazanski68ca5ee2021-04-27 16:09:16 +020032 DefaultGateway: nil,
Serge Bazanskic00318e2021-03-03 12:39:24 +010033 })
34
35 select {
Serge Bazanski68ca5ee2021-04-27 16:09:16 +020036 case <-time.After(100 * time.Millisecond):
Serge Bazanskic00318e2021-03-03 12:39:24 +010037 case <-ctx.Done():
Serge Bazanski68ca5ee2021-04-27 16:09:16 +020038 return
Serge Bazanskic00318e2021-03-03 12:39:24 +010039 }
40
41 fmt.Printf("NS: Got DHCP Lease\n")
42 s.Provider.Set(NetworkStatus{
43 ExternalAddress: net.ParseIP("203.0.113.24"),
Serge Bazanski68ca5ee2021-04-27 16:09:16 +020044 DefaultGateway: net.ParseIP("203.0.113.1"),
Serge Bazanskic00318e2021-03-03 12:39:24 +010045 })
46
47 select {
Serge Bazanski68ca5ee2021-04-27 16:09:16 +020048 case <-time.After(100 * time.Millisecond):
Serge Bazanskic00318e2021-03-03 12:39:24 +010049 case <-ctx.Done():
50 return
51 }
52
53 fmt.Printf("NS: DHCP Address changed\n")
54 s.Provider.Set(NetworkStatus{
55 ExternalAddress: net.ParseIP("203.0.113.103"),
Serge Bazanski68ca5ee2021-04-27 16:09:16 +020056 DefaultGateway: net.ParseIP("203.0.113.1"),
Serge Bazanskic00318e2021-03-03 12:39:24 +010057 })
58
59 time.Sleep(100 * time.Millisecond)
60}
61
62// ExampleValue_full demonstrates a typical usecase for Event Values, in which
63// a mock network service lets watchers know that the machine on which the code
64// is running has received a new network configuration.
65// It also shows the typical boilerplate required in order to wrap a Value (eg.
66// MemoryValue) within a typesafe wrapper.
67func ExampleValue_full() {
68 ctx, ctxC := context.WithCancel(context.Background())
69 defer ctxC()
70
71 // Create a fake NetworkService.
Tim Windelschmidt3b5a9172024-05-23 13:33:52 +020072 var ns NetworkService
Serge Bazanskic00318e2021-03-03 12:39:24 +010073
74 // Run an /etc/hosts updater. It will watch for updates from the NetworkService
75 // about the current IP address of the node.
76 go func() {
Serge Bazanski37110c32023-03-01 13:57:27 +000077 w := ns.Provider.Watch()
Serge Bazanskic00318e2021-03-03 12:39:24 +010078 for {
79 status, err := w.Get(ctx)
80 if err != nil {
81 break
82 }
83 if status.ExternalAddress == nil {
84 continue
85 }
86 // Pretend to write /etc/hosts with the newest ExternalAddress.
87 // In production code, you would also check for whether ExternalAddress has
88 // changed from the last written value, if writing to /etc/hosts is expensive.
89 fmt.Printf("/etc/hosts: foo.example.com is now %s\n", status.ExternalAddress.String())
90 }
91 }()
92
93 // Run fake network service.
94 ns.Run(ctx)
95
96 // Output:
97 // NS: Got DHCP Lease
98 // /etc/hosts: foo.example.com is now 203.0.113.24
99 // NS: DHCP Address changed
100 // /etc/hosts: foo.example.com is now 203.0.113.103
101}