-
Notifications
You must be signed in to change notification settings - Fork 2.8k
/
invoke.go
72 lines (61 loc) · 1.87 KB
/
invoke.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium
package cell
import (
"time"
"github.com/cilium/cilium/pkg/hive/internal"
)
type invoker struct {
funcs []namedFunc
}
type namedFunc struct {
name string
fn any
}
type InvokerList interface {
AppendInvoke(func() error)
}
func (i *invoker) invoke(cont container) error {
for _, afn := range i.funcs {
log.WithField("function", afn.name).Debug("Invoking")
t0 := time.Now()
if err := cont.Invoke(afn.fn); err != nil {
log.WithError(err).WithField("", afn.name).Error("Invoke failed")
return err
}
d := time.Since(t0)
log.WithField("duration", d).WithField("function", afn.name).Info("Invoked")
}
return nil
}
func (i *invoker) Apply(c container) error {
// Remember the scope in which we need to invoke.
invoker := func() error { return i.invoke(c) }
// Append the invoker to the list of invoke functions. These are invoked
// prior to start to build up the objects. They are not invoked directly
// here as first the configuration flags need to be registered. This allows
// using hives in a command-line application with many commands and where
// we don't yet know which command to run, but we still need to register
// all the flags.
return c.Invoke(func(l InvokerList) {
l.AppendInvoke(invoker)
})
}
func (i *invoker) Info(container) Info {
n := NewInfoNode("")
for _, namedFunc := range i.funcs {
n.AddLeaf("🛠️ %s: %s", namedFunc.name, internal.PrettyType(namedFunc.fn))
}
return n
}
// Invoke constructs a cell for invoke functions. The invoke functions are executed
// when the hive is started to instantiate all objects via the constructors.
func Invoke(funcs ...any) Cell {
namedFuncs := []namedFunc{}
for _, fn := range funcs {
namedFuncs = append(
namedFuncs,
namedFunc{name: internal.FuncNameAndLocation(fn), fn: fn})
}
return &invoker{funcs: namedFuncs}
}