MCPcopy
hub / github.com/tailscale/tailscale / ExampleDeferredInit

Function ExampleDeferredInit

types/lazy/deferred_test.go:14–90  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

12)
13
14func ExampleDeferredInit() {
15 // DeferredInit allows both registration and invocation of the
16 // deferred funcs. It should remain internal to the code that "owns" it.
17 var di DeferredInit
18 // Deferred funcs will not be executed until [DeferredInit.Do] is called.
19 deferred := di.Defer(func() error {
20 fmt.Println("Internal init")
21 return nil
22 })
23 // [DeferredInit.Defer] reports whether the function was successfully deferred.
24 // A func can only fail to defer if [DeferredInit.Do] has already been called.
25 if deferred {
26 fmt.Printf("Internal init has been deferred\n\n")
27 }
28
29 // If necessary, the value returned by [DeferredInit.Funcs]
30 // can be shared with external code to facilitate deferring
31 // funcs without allowing it to call [DeferredInit.Do].
32 df := di.Funcs()
33 // If a certain init step must be completed for the program
34 // to function correctly, and failure to defer it indicates
35 // a coding error, use [DeferredFuncs.MustDefer] instead of
36 // [DeferredFuncs.Defer]. It panics if Do() has already been called.
37 df.MustDefer(func() error {
38 fmt.Println("External init - 1")
39 return nil
40 })
41 // A deferred func may return an error to indicate a failed init.
42 // If a deferred func returns an error, execution stops
43 // and the error is propagated to the caller.
44 df.Defer(func() error {
45 fmt.Println("External init - 2")
46 return errors.New("bang!")
47 })
48 // The deferred function below won't be executed.
49 df.Defer(func() error {
50 fmt.Println("Unreachable")
51 return nil
52 })
53
54 // When [DeferredInit]'s owner needs initialization to be completed,
55 // it can call [DeferredInit.Do]. When called for the first time,
56 // it invokes the deferred funcs.
57 err := di.Do()
58 if err != nil {
59 fmt.Printf("Deferred init failed: %v\n", err)
60 }
61 // [DeferredInit.Do] is safe for concurrent use and can be called
62 // multiple times by the same or different goroutines.
63 // However, the deferred functions are never invoked more than once.
64 // If the deferred init fails on the first attempt, all subsequent
65 // [DeferredInit.Do] calls will return the same error.
66 if err = di.Do(); err != nil {
67 fmt.Printf("Deferred init failed: %v\n\n", err)
68 }
69
70 // Additionally, all subsequent attempts to defer a function will fail
71 // after [DeferredInit.Do] has been called.

Callers

nothing calls this directly

Calls 6

FuncsMethod · 0.95
DoMethod · 0.95
DeferMethod · 0.80
PrintfMethod · 0.80
MustDeferMethod · 0.80
NewMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…