USAGE
3CONFIGURATION
The framework behavior is defined by the trafilo_config_t structure. The caller specifies network parameters, concurrency counts, window dimensions, and lifecycle callbacks.
trafilo_config_t cfg = {
/* Network */
.port = 9999,
.recv_timeout_ms = 100,
/* Threading & Concurrency */
.num_workers = 4,
.num_buckets = 127,
/* Sliding Window */
.window_size_ms = 5000,
.slide_interval_ms = 1000,
/* Callbacks */
.parse = parse_fn,
.event_free = event_free_fn,
.handle = handle_fn,
.sink = sink_fn,
.state_init = state_init_fn,
.state_free = state_free_fn,
}; CALLBACK CONTRACTS
Memory Ownership
The parse_fn receives a raw UDP buffer. It allocates an event_t, populates the key and payload fields, and returns 0. Trafilo takes ownership of the event. When the event expires from the sliding window, Trafilo invokes event_free_fn. The caller frees memory allocated for the key, payload, and the event pointer.
State Initialization
The framework invokes state_init_fn(const char *key) upon encountering a key for the first time. The caller allocates and returns the state structure. If state_init_fn is NULL, or returns NULL, the framework delegates state management to the caller.
Execution Guarantees
The framework invokes handle_fn(const event_t *event, void *user_state) while holding the bucket lock. Operations accessing user_state are thread-safe with respect to the associated key. The caller must not acquire internal mutexes within the state object unless sharing the structure outside the Trafilo context.
Sink Output
The framework invokes sink_fn when the slide_interval_ms period concludes. The function receives a window_result_t containing the current event count, timestamp boundaries, and the associated user_state.
MANUAL INJECTION
The caller injects data directly into the working queue via trafilo_emit. This function bypasses the UDP socket. It returns 0 on success, and -1 if the queue is full or the framework is shutting down.
trafilo_emit(t, "user_login 192.168.1.1", 23);