Skip to content

ENT-14195 2. cf-reactor data structure and polling - #6354

Merged
olehermanse merged 3 commits into
cfengine:masterfrom
victormlg:event-handling-2-polling
Sep 23, 2026
Merged

olehermanse merged 3 commits into
cfengine:masterfrom
victormlg:event-handling-2-polling

Conversation

@victormlg

@victormlg victormlg commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

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 called key) and a global hashmap mapping this key to a bundle which 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 in when bodies:

body when file_deleted(filename)
{
    file_deleted => "$(filename)";
}

Every event type must have defined:

  • A check function (called check_callback in Watcher): 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 returns true.
  • A state: This is a struct whose interpretation depends on the event type (thus being declared as void *). 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.
  • A state destroying function (called 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 Watcher object with the right functions inside WatcherRegister() and also call the right "...PayloadNew()" function.

Polling

ReactorContextInitialize() sets up all the necessary data structures for polling, and then starts WatcherThreadMain, which polls for events as follows:

  • It iterates through each watcher in the global list of watchers.
  • If the elapsed time exceeds the watcher's interval, it runs check_callback to determine whether an event has been triggered.
  • If an event was triggered, it pushes the watcher's key (the promise name) onto a thread-safe queue, then signals the file descriptor via WakeupChannelNotify, which select(2) will pick up on its next iteration. It then goes back to sleep.

In parallel, EventWatcherHandleEvents, called from within ReactorContextHandleEvents, reads from the file descriptor with WakeupChannelReadFd() 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, which cf-reactor then runs (in another thread or subprocess)

@victormlg victormlg changed the title Event handling 2 polling ENT-14195 2. cf-reactor data structure and polling Sep 7, 2026
@cf-bottom

Copy link
Copy Markdown

Thank you for submitting a pull request! Maybe @craigcomstock can review this?

@olehermanse

Copy link
Copy Markdown
Member

@victormlg please rebase this one :)

@victormlg
victormlg force-pushed the event-handling-2-polling branch 2 times, most recently from 8c1a6a0 to 40ae51a Compare September 17, 2026 09:31
Comment thread cf-reactor/reactor_context.c Fixed
Comment thread cf-reactor/reactor_context.c Fixed
Comment thread cf-reactor/watcher.c Fixed
@victormlg
victormlg force-pushed the event-handling-2-polling branch from 40ae51a to f4fec79 Compare September 17, 2026 11:33
@victormlg
victormlg requested a review from larsewi September 17, 2026 12:02
@victormlg
victormlg force-pushed the event-handling-2-polling branch from f4fec79 to 5109eef Compare September 17, 2026 12:03

@larsewi larsewi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did not review the whole thing yet. Here is what I have so far

Comment thread cf-reactor/reactor_context.c
Comment thread cf-reactor/wakeup_channel.h Outdated
Comment thread cf-reactor/watcher.c Outdated
Comment thread cf-reactor/watcher.c Outdated
@victormlg
victormlg force-pushed the event-handling-2-polling branch 2 times, most recently from e5add04 to 639dac8 Compare September 18, 2026 08:01
@olehermanse

Copy link
Copy Markdown
Member

On an agent run, cf-agent makes cf-reactor read the policy, and rebuilds the list of watchers and the hashmap using the single function

I commented on this in the README PR as well - why should cf-agent be involved? cf-reactor can do this on its own.

@victormlg

Copy link
Copy Markdown
Contributor Author

On an agent run, cf-agent makes cf-reactor read the policy, and rebuilds the list of watchers and the hashmap using the single function

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.

@olehermanse

Copy link
Copy Markdown
Member

@cf-bottom jenkins, please

@cf-bottom

Copy link
Copy Markdown

@craigcomstock craigcomstock left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read through about half of the changes and researched claude's "low" effort code review results.

Comment thread cf-reactor/reactor_context.c Outdated
Comment thread cf-reactor/reactor_context.c
Comment thread cf-reactor/reactor_context.c Outdated
Comment thread cf-reactor/README.md
Comment thread cf-reactor/wakeup_channel.c Outdated
Comment thread cf-reactor/wakeup_channel.c
Comment thread cf-reactor/watcher.c
Comment thread cf-reactor/watcher.c
Comment thread cf-reactor/watcher.c
Comment thread cf-reactor/wakeup_channel.c Outdated
@victormlg
victormlg force-pushed the event-handling-2-polling branch from 639dac8 to a8a7cba Compare September 21, 2026 08:41
Comment thread cf-reactor/watcher.c Dismissed

@craigcomstock craigcomstock left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the signals refactor.

All that I'd like to see is a few TODO comments.

Comment thread cf-reactor/watcher.c
Comment thread cf-reactor/watcher.c
@victormlg
victormlg force-pushed the event-handling-2-polling branch from a8a7cba to 8a52585 Compare September 21, 2026 17:31
Comment thread cf-reactor/watcher.c Outdated
Comment thread cf-reactor/watcher.c Outdated
Comment thread cf-reactor/watcher.c Outdated
Comment thread cf-reactor/watcher.c Outdated
@victormlg
victormlg force-pushed the event-handling-2-polling branch from 8a52585 to 0ad9903 Compare September 22, 2026 06:52
@olehermanse

Copy link
Copy Markdown
Member

@cf-bottom jenkins, please

@cf-bottom

Copy link
Copy Markdown

@larsewi larsewi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some smaller comments

Comment thread cf-reactor/watcher.c
Comment thread cf-reactor/watcher.c
Comment thread cf-reactor/watcher.c Outdated
Comment thread cf-reactor/reactor_context.c
Comment thread cf-reactor/watcher.c Outdated
Comment thread cf-reactor/watcher.c Outdated
@victormlg
victormlg force-pushed the event-handling-2-polling branch from 0ad9903 to 8776986 Compare September 23, 2026 08:36
Comment thread cf-reactor/stoppable_thread.c Fixed
Comment thread cf-reactor/stoppable_thread.c Fixed
@olehermanse

Copy link
Copy Markdown
Member

@cf-bottom please test this in jenkins.

Comment thread cf-reactor/watcher.c Outdated
@olehermanse
olehermanse requested a review from larsewi September 23, 2026 11:50
@cf-bottom

Copy link
Copy Markdown

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>
@victormlg
victormlg force-pushed the event-handling-2-polling branch from 8776986 to d3f49f0 Compare September 23, 2026 12:30
@olehermanse
olehermanse merged commit c0d6090 into cfengine:master Sep 23, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

6 participants