Skip to content

Overhaul stats: simplify how the AnnounceHandler persist number of downloads in tracker-core package #1524

@josecelano

Description

@josecelano

Now that the `torrent-repository is emitting events, we can simplify the announce handler in the tracker-core package.

The bittorrent_tracker_core::announce_handler::AnnounceHandler has a method to handle the announce request:

    pub async fn announce(
        &self,
        info_hash: &InfoHash,
        peer: &mut peer::Peer,
        remote_client_ip: &IpAddr,
        peers_wanted: &PeersWanted,
    ) -> Result<AnnounceData, AnnounceError> {
        self.whitelist_authorization.authorize(info_hash).await?;

        let opt_persistent_torrent = if self.config.tracker_policy.persistent_torrent_completed_stat {
            self.db_torrent_repository.load(info_hash)?
        } else {
            None
        };

        peer.change_ip(&assign_ip_address_to_peer(remote_client_ip, self.config.net.external_ip));

        let number_of_downloads_increased = self
            .in_memory_torrent_repository
            .upsert_peer(info_hash, peer, opt_persistent_torrent)
            .await;

        if self.config.tracker_policy.persistent_torrent_completed_stat && number_of_downloads_increased {
            self.db_torrent_repository.increase_number_of_downloads(info_hash)?;
        }

        Ok(self.build_announce_data(info_hash, peer, peers_wanted).await)
    }

When persistent_torrent_completed_stat is enabled, it updates a DB counter with the number of downloads for that torrent.

I proposed a change here.

We can now:

  • Listen for events from the torrent-repository package.
  • Filter the event PeerDownloadCompleted.
  • When we received that event, we call the db_torrent_repository.increase_number_of_downloads(info_hash) function.

The downloads will be incremented asynchronously.

Pros:

  • Response should be faster; the peer does not have to wait until we increase the counter in the DB.
  • The announce method will be simpler. It does not have to handle metrics.
  • We can simplify the upsert_peer method. We don't need to return the boolean to know if downloads were increased.
  • The EventBus acts as a buffer to write to the database (to increase counters). We could use batches to increase many counters with one SQL sentence.

Cons:

  • It will be harder to follow what's happening by only reading the announce method. Anyway, we are intensively using events everywhere.
  • It can be inefficient to listen to all torrent-repository events. Ideally we should be able to listen only to the PeerDownloadCompleted event. But I think that would not be possible if we don't use another EventBus.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions