Skip to content

Overhaul stats: Handle lagging in event listeners channels #1449

@josecelano

Description

@josecelano

Relates to: #1385

When I run the tracker in the demo server, stats stop working after a while, and I get this error in logs:

tracker  | 2025-04-14T08:43:30.045862Z ERROR torrust_udp_tracker_server::statistics::event::listener: Error receiving udp tracker server event: Lagged(9)

The problem was produced when I switched to Tokio broadcast channels to allow multiple event listeners.

Lagging is not handled in the event listener. For example, the UDP tracker server event listener:

use tokio::sync::broadcast;
use torrust_tracker_clock::clock::Time;

use super::handler::handle_event;
use crate::event::Event;
use crate::statistics::repository::Repository;
use crate::CurrentClock;

pub async fn dispatch_events(mut receiver: broadcast::Receiver<Event>, stats_repository: Repository) {
    loop {
        match receiver.recv().await {
            Ok(event) => handle_event(event, &stats_repository, CurrentClock::now()).await,
            Err(e) => {
                tracing::error!("Error receiving udp tracker server event: {:?}", e);
                break;
            }
        }
    }
}

The channel capacity is 1024, so when unhandled events reach the channel capacity, we receive an error in the loop that breaks the loop, stopping the listener.

Since:

  • We only have one listener now to update metrics.
  • I want metrics to be exact.

As a temporary solution, I will increase the channel capacity to have the same effect as when we used a mspc channel.

I will also continue the loop when the listener receives that error.

IMPORTANT: The metrics will NOT be exact if there are lagged events.

cc @da2ce7

Alternative solution 1

Restore the mspc channel for metrics.

Pros:

  • Precise metrics

Cons:

  • Slower request processing? The request has to wait until the metrics are updated.
  • We will need two channels: one mpsc channel for metrics and a broadcast channel for generic listeners.

NOTE: The main reason I wanted to have multiple listeners is that I want third-party software to be able to build their own metrics from tracker events (by registering their event listeners).

Metadata

Metadata

Assignees

Labels

BugIncorrect BehaviorNeeds FeedbackWhat dose the Community Think?

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions