diff --git a/benchmarks/cli.py b/benchmarks/cli.py index 5340bfb..409574b 100644 --- a/benchmarks/cli.py +++ b/benchmarks/cli.py @@ -48,8 +48,18 @@ def run(config: Path, experiment: str): if experiment not in experiments: print(f'Experiment {experiment} not found in {config}.') sys.exit(-1) - experiments[experiment].run() + experiments[experiment].build().run() + + +def _init_logging(): + import logging + + logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' + ) if __name__ == '__main__': + _init_logging() app() diff --git a/benchmarks/core/experiments/static_experiment.py b/benchmarks/core/experiments/static_experiment.py index 4bbb46e..d62e930 100644 --- a/benchmarks/core/experiments/static_experiment.py +++ b/benchmarks/core/experiments/static_experiment.py @@ -4,6 +4,10 @@ from benchmarks.core.experiments.experiments import Experiment from benchmarks.core.network import TInitialMetadata, TNetworkHandle, Node from benchmarks.core.utils import ExperimentData +import logging + +logger = logging.getLogger(__name__) + class StaticDisseminationExperiment(Generic[TNetworkHandle, TInitialMetadata], Experiment): def __init__( @@ -29,13 +33,21 @@ class StaticDisseminationExperiment(Generic[TNetworkHandle, TInitialMetadata], E ] ) + logger.info('Running experiment with %d seeders and %d leechers', + len(seeders), len(leechers)) + with self.data as (meta, data): cid = None + logger.info('Seeding data') for node in seeders: cid = node.seed(data, meta if cid is None else cid) assert cid is not None # to please mypy + logger.info('Setting up leechers') downloads = [node.leech(cid) for node in leechers] - for download in downloads: + + logger.info('Now waiting for downloads to complete') + for i, download in enumerate(downloads): download.await_for_completion() + logger.info('Download %d / %d completed', i + 1, len(downloads)) diff --git a/benchmarks/core/experiments/tests/test_static_experiment.py b/benchmarks/core/experiments/tests/test_static_experiment.py index 03c9c30..89974e4 100644 --- a/benchmarks/core/experiments/tests/test_static_experiment.py +++ b/benchmarks/core/experiments/tests/test_static_experiment.py @@ -20,6 +20,10 @@ class MockNode(Node[MockHandle, str]): self.leeching: Optional[MockHandle] = None self.download_was_awaited = False + @property + def name(self) -> str: + return 'mock_node' + def seed( self, file: Path, diff --git a/benchmarks/core/network.py b/benchmarks/core/network.py index ae7f689..bdf3f75 100644 --- a/benchmarks/core/network.py +++ b/benchmarks/core/network.py @@ -23,6 +23,12 @@ class DownloadHandle(ABC): class Node(ABC, Generic[TNetworkHandle, TInitialMetadata]): """A :class:`Node` represents a peer within a file sharing network.""" + @property + @abstractmethod + def name(self) -> str: + """A network-wide name for this node.""" + pass + @abstractmethod def seed( self, diff --git a/benchmarks/deluge/config.py b/benchmarks/deluge/config.py index 6e8dae7..e27b3ea 100644 --- a/benchmarks/deluge/config.py +++ b/benchmarks/deluge/config.py @@ -56,8 +56,8 @@ class DelugeExperimentConfig(ExperimentBuilder[DelugeDisseminationExperiment]): StaticDisseminationExperiment( network=[ RealDelugeNode( - name=f'deluge-{i}', - volume=self.shared_volume_path / f'deluge-{i}', + name=f'deluge-{i + 1}', + volume=self.shared_volume_path, daemon_port=node.daemon_port, daemon_address=str(node.address), ) diff --git a/benchmarks/deluge/deluge_node.py b/benchmarks/deluge/deluge_node.py index 822189f..5a7b7f5 100644 --- a/benchmarks/deluge/deluge_node.py +++ b/benchmarks/deluge/deluge_node.py @@ -4,7 +4,7 @@ import shutil from dataclasses import dataclass from io import BytesIO from pathlib import Path -from time import time +from time import time, sleep from typing import List, Union, Optional, Self, Dict, Any import pathvalidate @@ -39,7 +39,7 @@ class DelugeNode(SharedFSNode[Torrent, DelugeMeta]): if not pathvalidate.is_valid_filename(name): raise ValueError(f'Node name must be a valid filename (bad name: "{name}")') - self.name = name + self._name = name self.downloads_root = volume / name / 'downloads' self._rpc: Optional[DelugeRPCClient] = None @@ -54,6 +54,10 @@ class DelugeNode(SharedFSNode[Torrent, DelugeMeta]): self._init_folders() + @property + def name(self) -> str: + return self._name + def wipe_all_torrents(self): torrent_ids = list(self.rpc.core.get_torrents_status({}, []).keys()) if torrent_ids: @@ -147,4 +151,6 @@ class DelugeDownloadHandle(DownloadHandle): if status[b'is_seed']: return True + sleep(0.5) + return False