Skip to content
This repository has been archived by the owner on Sep 14, 2020. It is now read-only.

Question: Dynamically adding events #267

Open
dgr237 opened this issue Dec 11, 2019 · 2 comments
Open

Question: Dynamically adding events #267

dgr237 opened this issue Dec 11, 2019 · 2 comments
Labels
question Further information is requested

Comments

@dgr237
Copy link

dgr237 commented Dec 11, 2019

Is it possible to dynamically register/unregister event handlers? I have a use case where when a Custom Resource Definition is created/deleted (which I am handling through on.delete and on.create handlers) I want to dynamically listen with an on.event handler for instances of the crd being created/updated/deleted.

Is this possible and if so how would I do this?

@nolar nolar added the question Further information is requested label Dec 11, 2019
@nolar
Copy link
Contributor

nolar commented Dec 11, 2019

I think, it is possible. Though it was never an intended use-case, probably can be broken in the future, and the consequences of doing so are unknown.

One problem that I see right now: there is not un-registering the handlers at the moment, but it can be easily added.


Another way is to use the operator embedding with kopf.operator(). The intention is to embed operator pattern ("watch-and-react") to arbitrary applications like UIs, etc. But a CRD-operator can be such a top-level application, with the per-kind-operators being the embedded operators.

  • whenever a CRD is created, construct a kopf.OperatorRegistry(), create a flag (threading.Event or asyncio.Event), and spawn (fire-and-forget) an asyncio task or a new thread with these registry+flag as arguments.
  • remember the flag in the memo kwarg as memo.stopmenow = flag.
  • whenever a CRD is deleted, raise the flag as memo.stopmenow.set().

Or, similarly, you can remember and then cancel an asyncio.Task.


Do I get it right that you want to watch for the CRD definitions directly, and then additionally operate the resources of that CRD?

That case can be covered by #85 — though not implemented now. E.g., you would be able to watch for:

@kopf.on.event('*', '*', '*')
def create_anything(resource, body, **_):
    pass

@kopf.on.event('zalando.org', '*', 'kopfexamples')
def create_any_version_of_kex(resource, body, **_):
    pass

@kopf.on.event('zalando.org', 'v1', '*')
def create_any_resource_type(resource, body, **_):
    pass

... and the framework would do the discovery and live-updating of the CRDs (actually, of any RDs, custom and built-in).

Since recently, when kopf.clients.discovery and background activities (now: startup, cleanup, authentication) were added, this feature is at least implementable.

Though, I never put it to a priority list, as could not find a realistic use-case.

@fsniper
Copy link

fsniper commented Jan 28, 2020

I am also working on a kind of related use case.

I have a static CRD that I watch, and this CRD has a list of other kinds (group/version/kind) to watch and operate on.

I started calling kopf.on.event decorators as methods to register new watchers. This works as expected.

def manifest_created(**kwargs):
   print("A new manifest is created")

@kop.on.create('group','v1', 'crd')
def create(**kwargs):
   # this is acquired from the watched manifest
   r = ('group', 'version', 'kind') 
   kopf.on.create(*r)(manifest_created)

Of course unregister problem still applies. Probably looking into operator embedding would be easier than trying to unregister handlers.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants