ENT-14195 2. cf-reactor data structure and polling - #6354
Conversation
|
Thank you for submitting a pull request! Maybe @craigcomstock can review this? |
|
@victormlg please rebase this one :) |
8c1a6a0 to
40ae51a
Compare
40ae51a to
f4fec79
Compare
f4fec79 to
5109eef
Compare
larsewi
left a comment
There was a problem hiding this comment.
Did not review the whole thing yet. Here is what I have so far
e5add04 to
639dac8
Compare
I commented on this in the README PR as well - why should cf-agent be involved? cf-reactor can do this on its own. |
I forgot to update the description in the PR. The README doesn't mention this anymore. |
|
@cf-bottom jenkins, please |
|
Alright, I triggered a build: Jenkins: https://ci.cfengine.com/job/pr-pipeline/14671/ Packages: http://buildcache.cfengine.com/packages/testing-pr/jenkins-pr-pipeline-14671/ |
craigcomstock
left a comment
There was a problem hiding this comment.
I read through about half of the changes and researched claude's "low" effort code review results.
639dac8 to
a8a7cba
Compare
craigcomstock
left a comment
There was a problem hiding this comment.
thanks for the signals refactor.
All that I'd like to see is a few TODO comments.
a8a7cba to
8a52585
Compare
8a52585 to
0ad9903
Compare
|
@cf-bottom jenkins, please |
|
Sure, I triggered a build: Jenkins: https://ci.cfengine.com/job/pr-pipeline/14678/ Packages: http://buildcache.cfengine.com/packages/testing-pr/jenkins-pr-pipeline-14678/ |
0ad9903 to
8776986
Compare
|
@cf-bottom please test this in jenkins. |
|
Alright, I triggered a build: Jenkins: https://ci.cfengine.com/job/pr-pipeline/14692/ Packages: http://buildcache.cfengine.com/packages/testing-pr/jenkins-pr-pipeline-14692/ |
Signed-off-by: Victor Moene <victor.moene@northern.tech>
Signed-off-by: Victor Moene <victor.moene@northern.tech>
Signed-off-by: Victor Moene <victor.moene@northern.tech>
8776986 to
d3f49f0
Compare
Spec
In order to track all the events promises, we use two datastructures: a global list of
"Watcher", which is a struct associated with an event type and the promise name (also calledkey) and a global hashmap mapping thiskeyto abundlewhich is parsed from the policy.cf-reactor reads the policy periodically, and when it does, rebuilds the list of watchers and the hashmap using the single function
WatcherRegister(key, event_type, state, bundle, interval). Each events promise is associated with an event type, which is defined inwhenbodies:Every event type must have defined:
check_callbackinWatcher): This is a function defined specifically for the event that checks if the conditions holds. For example, in case of file deletion, we check if the file doesn't exist anymore compare to the last time we checked. If yes, then it returnstrue.state: This is a struct whose interpretation depends on the event type (thus being declared asvoid *). We typically need some state that we compare between each event-check. In the case of file deletion, we need to know the name of the file we are watching, and whether the file existed last time we checked.destroy_state): This is simply a function to free the state associated with the event type.Also, we need a function that will create the state. That's what
FileWatcherPayloadNew()does.So each event type we add in the future just need to have these four things defined, and we need to create the
Watcherobject with the right functions insideWatcherRegister()and also call the right"...PayloadNew()"function.Polling
ReactorContextInitialize()sets up all the necessary data structures for polling, and then startsWatcherThreadMain, which polls for events as follows:interval, it runscheck_callbackto determine whether an event has been triggered.key(the promise name) onto a thread-safe queue, then signals the file descriptor viaWakeupChannelNotify, whichselect(2)will pick up on its next iteration. It then goes back to sleep.In parallel,
EventWatcherHandleEvents, called from withinReactorContextHandleEvents, reads from the file descriptor withWakeupChannelReadFd()once notified that an event has occurred, and pops the thread-safe queue until it's empty. Each key popped from the queue is looked up in the global hashmap to retrieve the corresponding bundle, whichcf-reactorthen runs (in another thread or subprocess)