-
Notifications
You must be signed in to change notification settings - Fork 87
How to periodly poll something? #122
Comments
@Kiddinglife Sorry, I didn't get the part with replicasets. But for polling something in Kopf you can use the It is better if resuming is used on combination with @kopf.on.resume('zalando.org', 'v1', 'kopfexamples')
@kopf.on.create('zalando.org', 'v1', 'kopfexamples')
def start_poller(**kwargs):
threading.Thread(target=poller, kwargs=kwargs).start()
def poller(**kwargs):
while shouldstop:
check_it()
change_it()
time.sleep(60) Thread deduplication can be additionally secured with threads = {}
@kopf.on.resume('zalando.org', 'v1', 'kopfexamples')
@kopf.on.create('zalando.org', 'v1', 'kopfexamples')
def start_poller(**kwargs):
uid = kwargs['uid']
if uid not in threads or not threads[uid].isAlive():
shouldstop = threading.Event()
thread = threading.Thread(target=poller, args=(shouldstop,), kwargs=kwargs)
threads[uid] = (thread, shouldstop)
thread.start()
else:
pass # already running
@kopf.on.delete('zalando.org', 'v1', 'kopfexamples')
def stop_polling(uid, **kwargs):
thread, shouldstop = threads[uid]
shouldstop.set()
thread.join() # can take ~60 seconds
del threads[uid]
def poller(shouldstop, **kwargs):
while not shouldstop.is_set():
......
time.sleep(60) |
@nolar is there any advantage of using dedicated threads for polling ? Versus using asyncio based libraries, like https://github.com/gawel/aiocron ? |
@eshepelyuk Cron-based functions can be sufficient for some cases. But they are unaware of Kubernetes resources in any form. First of all, you might have multiple resource to serve, parametrised with their own values in Second, the polling is supposed to stop once the resource is gone. You would need to explicitly stop that I believe, one way or another, it is doable on a case-by-case basis. You can also start and cancel an asyncio task from creation+resuming or deletion handlers accordingly — and that will be enough. The difference is only in the amount of boilerplate code needed for this extra non-domain logic. Disclaimer: I never used On the other hand, Kopf's daemons & timers are fully Kubernetes-specialised and resource-aware: they run individually for each resource (and access its Kopf does not have anything with cron-like schedules right now (e.g. |
@nolar the entire question was about different topic
|
@eshepelyuk Ah, I see. Sorry for misunderstanding. There is no big advantage of using threads over asyncio tasks. Actually, it is a disadvantage — threads are non-stoppable from outside, while asyncio tasks are cancellable. However, as I have learned the hard way, asyncio, asynchronous programming, and cooperative concurrency are difficult to understand for many people. But they know threads, because it is an old and proven tool, explained in many books, and considered a must-have for software engineering skillset. So, by default, I usually explain ideas in plain-and-simple tech tools, in order to not bring complicated side-topics like asyncio to the table. Not to mention that if people start using synchronous API client libraries in asynchronous tasks, this will be a disaster (in runtime). And most of the K8s API client libraries are still synchronous, especially the official one. A side-note: for the same reason, Kopf supports both sync and async handlers, with usual Nowadays, Kopf is fully async inside indeed. And there are daemons! I will come back to this question once 0.27 is released in a few days. |
@nolar thnx your intention of explaning via threads is clear now. one more question to continue - daemons and timers are bound to some K8S resource now and are active only when that tracked resource exists. I have a vision of how to overcome this - i.e. create a didicated CRD for this prometheus polling and associate KOPF timer or daemon to that resource. |
@eshepelyuk For me, it is not clear if the requested polling is global, or per-resource. I would assume that the intention was to poll the metrics of specific pods of a specific app/deployment, in order to scale it — and repeat it for each of the apps/deployments. So, it would be resource-bound. But if that is a global single-instance polling, then start a thread or a task explicitly, and poll from there. You can do it from |
@nolar motivation is clearly described, reasonable and complete :) |
Hi folks,
for example,
kubectl autoscale deployment xxx --cpu-percent=50 --min=1 --max=10
but autoscale only supports k8s-built-in api resources like replicaset, deployment and statefulset.
I need my controller to periodly poll the premetheus server for some metrics so that my controller can automatically scale up or scale down pods.
thanks.
The text was updated successfully, but these errors were encountered: