4

I'm writing a custom controller for Kubernetes in Go with the help of client-go. It is based on the sample-controller and working great so far.

The SharedIndexInformer has the option to periodically resync all objects. (Parameter resyncPeriod is set to 30 seconds in the sample-controller.)

Is there a way to force a resync immediately?

The code which seems to handle the periodic resync seems to call store.Resync(). I've tried calling fooInformer.Informer().GetStore().Resync(). The call succeeds, but the resync is not happening. What did I miss?


I'm using client-go v0.17.2 and the server is EKS v1.14.9-eks-c0eccc.

3 Answers3

1

Upon calling fooInformer.Informer().GetStore().Resync() you are using Resync function/method of the Store type defined in: client-go/tools/cache/store.go

And there we can see the following:

In the Store type definition:

// Resync is meaningless in the terms appearing here but has
// meaning in some implementations that have non-trivial
// additional behavior (e.g., DeltaFIFO).
Resync() error

And in the Resync definition further below:

// Resync is meaningless for one of these
func (c *cache) Resync() error {
return nil
}

Unless you actually have some other class to do the Resync, this is supposed to really do nothing.

That is why

The call succeeds, but the resync is not happening.

Hope that helps!

Nick
  • 1,882
  • 11
  • 16
1

This is not possible.

The cache.Store that does the periodic resync is instantiated in newInformer in k8s.io/client-go/tools/cache/controller.go as a cache.DeltaFIFO queue:

    // This will hold incoming changes. Note how we pass clientState in as a
    // KeyLister, that way resync operations will result in the correct set
    // of update/delete deltas.
    fifo := NewDeltaFIFOWithOptions(DeltaFIFOOptions{
        KnownObjects:          clientState,
        EmitDeltaTypeReplaced: true,
    })

This is returned by cache.New() as an unexported field cache.controller{}.config.Queue, which there is no exported function for accessing- so no way to manually call Resync().

0

You can achieve this by listing every object from the informer store, then calling ResourceEventHandlerFuncs's AddFunc (usually xxxController.OnAddXxx).

for _, v := range xxxController.xxxInformer.GetStore().List() {
    xxxController.OnAddXxx(v)
}

Or, if you'd like to hack, you can use reflect

field := reflect.ValueOf(xxxController.xxxInformer).Elem().FieldByName("controller").Elem().Elem().FieldByName("reflector").Elem().FieldByName("store")
reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Interface().(*cache.DeltaFIFO).Resync()
Kevin
  • 2,775
  • 4
  • 16
  • 27