Skip to main content

Module listen

Module listen 

Source
Expand description

§Capture listening plugins

Plugins with capture listening capability can receive notifications whenever a capture is started or stopped. Note that a capture may be stopped and restarted multiple times over the lifetime of a plugin.

§Background tasks

Capture listening plugins receive a reference to a thread pool, which can be used to submit “routines” (tasks running in a separate thread, effectively).

Note due to API limitations, this functionality cannot be made fully leak-free. When a routine gets dropped at precisely the wrong point in time (as it starts executing), it will leak a small amount of memory. Consider never dropping routines at all, and instead use some mechanism to signal to the routine that it should stop rescheduling itself (e.g., an atomic boolean in a shared struct).

Note there is no built-in mechanism to stop a running routine, so you should avoid doing this in the routine:

loop {
    do_something();
    std::thread::sleep(some_time);
}

Instead, have your routine just do a single iteration and request a rerun from the scheduler:

do_something();
std::thread::sleep(some_time);
std::ops::ControlFlow::Continue(())

If you insist on using an infinite loop inside a routine, consider using e.g. BackgroundTask to manage the lifetime of the routine.

For your plugin to support event parsing, you will need to implement the CaptureListenPlugin trait and invoke the capture_listen_plugin macro, for example:

use falco_plugin::anyhow::Error;
use falco_plugin::base::Plugin;
use falco_plugin::{capture_listen_plugin, plugin};
use falco_plugin::listen::{CaptureListenInput, CaptureListenPlugin, Routine};

struct MyListenPlugin {
    tasks: Vec<Routine>,
}

impl Plugin for MyListenPlugin {
    // ...
}

impl CaptureListenPlugin for MyListenPlugin {
    fn capture_open(&mut self, listen_input: &CaptureListenInput) -> Result<(), Error> {
        log::info!("Capture started");
        self.tasks.push(listen_input.thread_pool.subscribe(|| {
            log::info!("Doing stuff in the background");
            std::thread::sleep(Duration::from_millis(500));
            std::ops::ControlFlow::Continue(())
        })?);

        Ok(())
    }

fn capture_close(&mut self, _listen_input: &CaptureListenInput) -> Result<(), Error> {
        log::info!("Capture stopped");
        self.tasks.clear(); // dropping the handles auto-unsubscribes
        Ok(())
    }
}

plugin!(MyListenPlugin);
capture_listen_plugin!(MyListenPlugin);

Structs§

CaptureListenInput
The input to a capture listening plugin
Routine
A handle for a routine running in the background
ThreadPool
Thread pool for managing background tasks

Traits§

CaptureListenPlugin
Support for capture listening plugins