// 在实例化一个变量之前,可以传入函数作用于它。pilot中的addFlags函数使用了类似“过滤器”的做法:
// NewPilotArgs constructs pilotArgs with default values.
func NewPilotArgs(initFuncs ...func(*PilotArgs)) *PilotArgs {
p := &PilotArgs{}
// Apply Default Values.
p.applyDefaults()
// Apply custom initialization functions.
for _, fn := range initFuncs {
fn(p)
}
...
serverArgs = bootstrap.NewPilotArgs(func(p *bootstrap.PilotArgs) {
// Set Defaults
p.CtrlZOptions = ctrlz.DefaultOptions()
// TODO replace with mesh config?
p.InjectionOptions = bootstrap.InjectionOptions{
InjectionDirectory: "./var/lib/istio/inject",
}
})
...
// ledger 保存了map 的之前状态,具有三个特征:
// 1. every unique state of the map is given a unique hash
// 2. prior states of the map are retained for a fixed period of time
// 2. given a previous hash, we can retrieve a previous state from the map, if it is still retained.
// 监控文件变化
// NewWatcher return with a FileWatcher instance that implemented with fsnotify.
func NewWatcher() FileWatcher {
return &fileWatcher{
workers: map[string]*workerState{},
// replaceable functions for tests
funcs: &patchTable{
newWatcher: fsnotify.NewWatcher,
addWatcherPath: func(watcher *fsnotify.Watcher, path string) error {
return watcher.Add(path)
},
},
}
}
// 写时复制,先分配好list的容量,然后append,节省内存分配时间
func (c *ControllerHandlers) AppendWorkloadHandler(f func(*WorkloadInstance, Event)) {
// Copy on write.
c.mutex.Lock()
handlers := make([]func(*WorkloadInstance, Event), 0, len(c.workloadHandlers)+1)
handlers = append(handlers, c.workloadHandlers...)
handlers = append(handlers, f)
c.workloadHandlers = handlers
c.mutex.Unlock()
}
// istio\pilot\pkg\serviceregistry\aggregate\controller.go
// 区分servicehandler workloadhandler instancehandler,后者是前两者的汇总
// Controller defines an event controller loop. Proxy agent registers itself
// with the controller loop and receives notifications on changes to the
// service topology or changes to the configuration artifacts.
//
// The controller guarantees the following consistency requirement: registry
// view in the controller is as AT LEAST as fresh as the moment notification
// arrives, but MAY BE more fresh (e.g. "delete" cancels an "add" event). For
// example, an event for a service creation will see a service registry without
// the service if the event is immediately followed by the service deletion
// event.
//
// Handlers execute on the single worker queue in the order they are appended.
// Handlers receive the notification event and the associated object. Note
// that all handlers must be appended before starting the controller.
type Controller interface {
// AppendServiceHandler notifies about changes to the service catalog.
AppendServiceHandler(f func(*Service, Event))
// AppendWorkloadHandler notifies about changes to workloads. This differs from InstanceHandler,
// which deals with service instances (the result of a merge of Service and Workload)
AppendWorkloadHandler(f func(*WorkloadInstance, Event))
// Run until a signal is received
Run(stop <-chan struct{})
// HasSynced returns true after initial cache synchronization is complete
HasSynced() bool
}
func newDiscoveryCommand() *cobra.Command {
return &cobra.Command{
Use: "discovery",
Short: "Start Istio proxy discovery service.",
// 注意 args 0 , cobra中分 command,arguments,flags
Args: cobra.ExactArgs(0),
PreRunE:...
...