Repository: istio/istio
File: pkg/kube/kclient/client.go (Go)

Code before:
type Filter = kubetypes.Filter

// New returns a Client for the given type.
// Internally, this uses a shared informer, so calling this multiple times will share the same internals.
func New[T controllers.ComparableObject](c kube.Client) Client[T] {
	return NewFiltered[T](c, Filter{})
}

// NewFiltered returns a Client with some filter applied.
// Internally, this uses a shared informer, so calling this multiple times will share the same internals. This is keyed on
// unique {Type,LabelSelector,FieldSelector}.
//
// Warning: if conflicting filter.ObjectTransform are used for the same key, the first one registered wins.
// This means there must only be one filter configuration for a given type using the same kube.Client.
// Use with caution.
func NewFiltered[T controllers.ComparableObject](c kube.Client, filter Filter) Client[T] {
	gvr := types.MustToGVR[T](types.MustGVKFromType[T]())
	inf := kubeclient.GetInformerFiltered[T](c, ToOpts(c, gvr, filter), gvr)
	return &fullClient[T]{
		writeClient: writeClient[T]{client: c},
		Informer:    newInformerClient[T](gvr, inf, filter),
	}
}

// NewDelayedWriter returns a "delayed" client for the given GVR that is writeable.
// It is the client's responsibility to not write to the client if the type is not available; the "Delay" is not impacting
// the write flow. The reason for this is typically the writes are for status, which is in response to the object existing,
// which implies the GVR exists.
func NewDelayedWriter[T controllers.ComparableObject](
	c kube.Client,
	gvr schema.GroupVersionResource,
	filter Filter,
) Client[T] {
	inf := NewDelayedInformer[T](c, gvr, kubetypes.StandardInformer, filter)
	return &fullClient[T]{
		writeClient: writeClient[T]{client: c},
		Informer:    inf,
	}
}

// NewDelayedInformer returns a "delayed" client for the given GVR. This is read-only.
// A delayed client is used for CRD watches when the CRD may or may not exist. When the CRD is not present, the client will return
// empty results for all operations and watch for the CRD creation. Once created, watchers will be started and read operations will
// begin returning results.
// HasSynced will only return true if the CRD was not present upon creation OR the watch is fully synced. This ensures the creation
// is fully consistent if the CRD was present during creation; otherwise it is eventually consistent.
func NewDelayedInformer[T controllers.ComparableObject](
	c kube.Client,
	gvr schema.GroupVersionResource,
	informerType kubetypes.InformerType,
	filter Filter,

Review comment (suggestion):
```suggestion
// It is the caller's responsibility to not write to the client if the type is not available; the "Delay" is not impacting
```

Code after:
type Filter = kubetypes.Filter

// New returns a Client for the given type.
// Internally, this uses a shared informer, so calling this multiple times will share the same internals.
func New[T controllers.ComparableObject](c kube.Client) Client[T] {
	return NewFiltered[T](c, Filter{})
}

// NewFiltered returns a Client with some filter applied.
// Internally, this uses a shared informer, so calling this multiple times will share the same internals. This is keyed on
// unique {Type,LabelSelector,FieldSelector}.
//
// Warning: if conflicting filter.ObjectTransform are used for the same key, the first one registered wins.
// This means there must only be one filter configuration for a given type using the same kube.Client.
// Use with caution.
func NewFiltered[T controllers.ComparableObject](c kube.Client, filter Filter) Client[T] {
	gvr := types.MustToGVR[T](types.MustGVKFromType[T]())
	inf := kubeclient.GetInformerFiltered[T](c, ToOpts(c, gvr, filter), gvr)
	return &fullClient[T]{
		writeClient: writeClient[T]{client: c},
		Informer:    newInformerClient[T](gvr, inf, filter),
	}
}

// NewFilteredDelayed returns a "delayed" client for the given GVR that is writeable.
// It is the caller's responsibility to not write to the client if the type is not available; the "Delay" is not impacting
// the write flow. The reason for this is typically the writes are for status, which is in response to the object existing,
// which implies the GVR exists.
func NewFilteredDelayed[T controllers.ComparableObject](
	c kube.Client,
	gvr schema.GroupVersionResource,
	filter Filter,
) Client[T] {
	inf := NewDelayedInformer[T](c, gvr, kubetypes.StandardInformer, filter)
	return &fullClient[T]{
		writeClient: writeClient[T]{client: c},
		Informer:    inf,
	}
}

// NewDelayedInformer returns a "delayed" client for the given GVR. This is read-only.
// A delayed client is used for CRD watches when the CRD may or may not exist. When the CRD is not present, the client will return
// empty results for all operations and watch for the CRD creation. Once created, watchers will be started and read operations will
// begin returning results.
// HasSynced will only return true if the CRD was not present upon creation OR the watch is fully synced. This ensures the creation
// is fully consistent if the CRD was present during creation; otherwise it is eventually consistent.
func NewDelayedInformer[T controllers.ComparableObject](
	c kube.Client,
	gvr schema.GroupVersionResource,
	informerType kubetypes.InformerType,
	filter Filter,