<p>I have been trying to watch some resources in my K8s cluster and after reading some blogs about watch vs informers, i've decided to go with Informers.</p>
<p>I came across this example of how to use one: <a href="https://github.com/Netflix-Skunkworks/kubernetes-client-java/blob/master/examples/src/main/java/io/kubernetes/client/examples/InformerExample.java" rel="nofollow noreferrer">https://github.com/Netflix-Skunkworks/kubernetes-client-java/blob/master/examples/src/main/java/io/kubernetes/client/examples/InformerExample.java</a></p>
<p>In the example, I see that the SharedIndexInformer is defined as such:</p>
<pre><code>        factory.sharedIndexInformerFor(
            (CallGeneratorParams params) -&gt; {
              return coreV1Api.listNodeCall(
                  null,
                  null,
                  null,
                  null,
                  null,
                  params.resourceVersion,
                  params.timeoutSeconds,
                  params.watch,
                  null,
                  null);
            },
            V1Node.class,
            V1NodeList.class);
</code></pre>
<p>Based on my understanding of how lambdas are written, this basically says that we're creating a <code>sharedIndexInformer</code> from the factory by passing it a param Call (returned by coreV1Api.listNodeCall).</p>
<p>The Call object is created by this dynamic method which takes in a <code>CallGeneratorParams</code> argument.</p>
<p>I do not seem to understand how and where this argument is passed in from in the case of a SharedInformerFactory. It's very evident that some fields within the <code>params</code> variable is being used in building the <code>listNodeCall</code> but where and how is this object constructed ?</p>

<p>Well it's a ride down a rabbit hole.</p>
<blockquote>
<p>I suggest to keep the diagrams <a href="https://github.com/huweihuang/kubernetes-notes/blob/master/code-analysis/kube-controller-manager/sharedIndexInformer.md" rel="nofollow noreferrer">from the official docs</a> open in separate tab/window in order to appreciate the whole picture better.</p>
</blockquote>
<p>In order to understand this, you would have to look at the implementation of the <code>SharedInformerFactory</code>, especially the <a href="https://github.com/kubernetes-client/java/blob/332c3a43bbd96b6814947f1f8543453b824ca253/util/src/main/java/io/kubernetes/client/informer/SharedInformerFactory.java#L115" rel="nofollow noreferrer">sharedIndexInformerFor</a> call.</p>
<p>Notice how the lambda is just passed further down to construct a new <a href="https://github.com/kubernetes-client/java/blob/332c3a43bbd96b6814947f1f8543453b824ca253/util/src/main/java/io/kubernetes/client/informer/ListerWatcher.java" rel="nofollow noreferrer">ListWatcher</a> instance <a href="https://github.com/kubernetes-client/java/blob/332c3a43bbd96b6814947f1f8543453b824ca253/util/src/main/java/io/kubernetes/client/informer/SharedInformerFactory.java#L194" rel="nofollow noreferrer">(method at line 194)</a>, which is then passed into a new <a href="https://github.com/kubernetes-client/java/blob/332c3a43bbd96b6814947f1f8543453b824ca253/util/src/main/java/io/kubernetes/client/informer/impl/DefaultSharedIndexInformer.java" rel="nofollow noreferrer">DefaultSharedIndexInformer</a> instance <a href="https://github.com/kubernetes-client/java/blob/332c3a43bbd96b6814947f1f8543453b824ca253/util/src/main/java/io/kubernetes/client/informer/SharedInformerFactory.java#L144" rel="nofollow noreferrer">(statement at line 144)</a>.</p>
<p>So now we have an instance of a <code>SharedIndexInformer</code> that passes the <code>ListerWatcher</code> yet further down to its <a href="https://github.com/kubernetes-client/java/blob/332c3a43bbd96b6814947f1f8543453b824ca253/util/src/main/java/io/kubernetes/client/informer/cache/Controller.java" rel="nofollow noreferrer">Controller</a> <a href="https://github.com/kubernetes-client/java/blob/332c3a43bbd96b6814947f1f8543453b824ca253/util/src/main/java/io/kubernetes/client/informer/impl/DefaultSharedIndexInformer.java#L99" rel="nofollow noreferrer">(constructor line 99)</a>. Now the <code>Controller</code> is started when the <code>Informer</code> itself runs (see the <code>run()</code> method).</p>
<p>To make it even more complex, the <code>Controller</code> uses a <code>Reflector</code> for .. stuff. A <code>Reflector</code> according to the <a href="https://github.com/kubernetes/kubernetes/blob/353f0a5eabe4bd8d31bb67275ee4beeb4655be3f/staging/src/k8s.io/client-go/tools/cache/reflector.go" rel="nofollow noreferrer">reflector.go</a></p>
<blockquote>
<p>Reflector watches a specified resource and causes all changes to be reflected in the given store.</p>
</blockquote>
<p>So its job is to call <code>list</code> and <code>watch</code> until it is told to stop. So when the <code>Controller</code> starts, it also schedules its <code>Reflector</code> to <a href="https://github.com/kubernetes-client/java/blob/332c3a43bbd96b6814947f1f8543453b824ca253/util/src/main/java/io/kubernetes/client/informer/cache/Controller.java#L116" rel="nofollow noreferrer">run periodically</a></p>
<p>At last. When the <code>Reflector</code> runs, it calls the <code>list</code> method, which  .. <em>drum roll</em> .. <a href="https://github.com/kubernetes-client/java/blob/332c3a43bbd96b6814947f1f8543453b824ca253/util/src/main/java/io/kubernetes/client/informer/SharedInformerFactory.java#L205" rel="nofollow noreferrer">executes the lambda</a> you were asking about. And the <code>param</code> variable in the lambda is .. <em>another drum roll</em> .. <a href="https://github.com/kubernetes-client/java/blob/332c3a43bbd96b6814947f1f8543453b824ca253/util/src/main/java/io/kubernetes/client/informer/cache/ReflectorRunnable.java#L89" rel="nofollow noreferrer">created in the Reflector here</a></p>
<p>Pretty neat, wouldn't you say?</p>
<p>Let me know, if you need further help/clarification.</p>
<p>Cheers</p>
