2024-11-26 19:53:59 -03:00
|
|
|
from itertools import islice
|
|
|
|
from pathlib import Path
|
|
|
|
from typing import List
|
|
|
|
|
2024-11-27 11:22:07 -03:00
|
|
|
from pydantic import BaseModel, Field, model_validator, HttpUrl
|
2024-11-26 19:53:59 -03:00
|
|
|
from torrentool.torrent import Torrent
|
2024-11-27 11:22:07 -03:00
|
|
|
from urllib3.util import parse_url
|
2024-11-26 19:53:59 -03:00
|
|
|
|
2024-11-27 11:22:07 -03:00
|
|
|
from benchmarks.core.config import Host, ExperimentBuilder
|
2024-12-03 18:32:48 -03:00
|
|
|
from benchmarks.core.experiments.experiments import IteratedExperiment, ExperimentEnvironment, Experiment, \
|
|
|
|
BoundExperiment
|
2024-11-26 19:53:59 -03:00
|
|
|
from benchmarks.core.experiments.static_experiment import StaticDisseminationExperiment
|
2024-11-27 11:22:07 -03:00
|
|
|
from benchmarks.core.utils import sample, RandomTempData
|
2024-11-28 17:17:26 -03:00
|
|
|
from benchmarks.deluge.deluge_node import DelugeMeta, DelugeNode
|
2024-12-03 18:32:48 -03:00
|
|
|
from benchmarks.deluge.tracker import Tracker
|
2024-11-26 19:53:59 -03:00
|
|
|
|
|
|
|
|
2024-11-27 11:22:07 -03:00
|
|
|
class DelugeNodeConfig(BaseModel):
|
2024-11-26 19:53:59 -03:00
|
|
|
address: Host
|
|
|
|
daemon_port: int
|
|
|
|
listen_ports: list[int] = Field(min_length=2, max_length=2)
|
|
|
|
|
|
|
|
|
2024-11-27 11:22:07 -03:00
|
|
|
class DelugeNodeSetConfig(BaseModel):
|
2024-12-06 13:52:57 -03:00
|
|
|
network_size: int = Field(gt=1)
|
2024-11-26 19:53:59 -03:00
|
|
|
address: str
|
|
|
|
daemon_port: int
|
|
|
|
listen_ports: list[int] = Field(min_length=2, max_length=2)
|
2024-12-06 13:27:43 -03:00
|
|
|
first_node_index: int = 1
|
2024-11-27 11:22:07 -03:00
|
|
|
nodes: List[DelugeNodeConfig] = []
|
2024-11-26 19:53:59 -03:00
|
|
|
|
|
|
|
@model_validator(mode='after')
|
|
|
|
def expand_nodes(self):
|
|
|
|
self.nodes = [
|
2024-11-27 11:22:07 -03:00
|
|
|
DelugeNodeConfig(
|
2024-11-28 15:52:38 -03:00
|
|
|
address=self.address.format(node_index=str(i)),
|
2024-11-26 19:53:59 -03:00
|
|
|
daemon_port=self.daemon_port,
|
|
|
|
listen_ports=self.listen_ports,
|
|
|
|
)
|
2024-12-06 13:27:43 -03:00
|
|
|
for i in range(self.first_node_index, self.first_node_index + self.network_size)
|
2024-11-26 19:53:59 -03:00
|
|
|
]
|
2024-11-27 11:22:07 -03:00
|
|
|
return self
|
2024-11-26 19:53:59 -03:00
|
|
|
|
|
|
|
|
2024-12-03 18:32:48 -03:00
|
|
|
DelugeDisseminationExperiment = IteratedExperiment[BoundExperiment[StaticDisseminationExperiment[Torrent, DelugeMeta]]]
|
2024-11-27 11:22:07 -03:00
|
|
|
|
|
|
|
|
|
|
|
class DelugeExperimentConfig(ExperimentBuilder[DelugeDisseminationExperiment]):
|
2024-11-28 09:46:21 -03:00
|
|
|
repetitions: int = Field(gt=0)
|
2024-11-26 19:53:59 -03:00
|
|
|
file_size: int = Field(gt=0)
|
|
|
|
seeders: int = Field(gt=0)
|
|
|
|
shared_volume_path: Path
|
2024-11-27 11:22:07 -03:00
|
|
|
tracker_announce_url: HttpUrl
|
|
|
|
nodes: List[DelugeNodeConfig] | DelugeNodeSetConfig
|
2024-11-26 19:53:59 -03:00
|
|
|
|
2024-11-27 11:22:07 -03:00
|
|
|
def build(self) -> DelugeDisseminationExperiment:
|
2024-12-03 18:32:48 -03:00
|
|
|
nodes_specs = self.nodes.nodes if isinstance(self.nodes, DelugeNodeSetConfig) else self.nodes
|
|
|
|
|
|
|
|
network = [
|
|
|
|
DelugeNode(
|
|
|
|
name=f'deluge-{i + 1}',
|
|
|
|
volume=self.shared_volume_path,
|
|
|
|
daemon_port=node_spec.daemon_port,
|
|
|
|
daemon_address=str(node_spec.address),
|
|
|
|
)
|
|
|
|
for i, node_spec in enumerate(nodes_specs)
|
|
|
|
]
|
|
|
|
|
|
|
|
tracker = Tracker(parse_url(str(self.tracker_announce_url)))
|
|
|
|
|
|
|
|
env = ExperimentEnvironment(
|
|
|
|
components=network + [tracker],
|
|
|
|
polling_interval=0.5,
|
|
|
|
)
|
|
|
|
|
2024-11-28 09:46:21 -03:00
|
|
|
repetitions = (
|
2024-12-03 18:32:48 -03:00
|
|
|
env.bind(StaticDisseminationExperiment(
|
|
|
|
network=network,
|
|
|
|
seeders=list(islice(sample(len(network)), self.seeders)),
|
2024-11-28 09:46:21 -03:00
|
|
|
data=RandomTempData(size=self.file_size,
|
|
|
|
meta=DelugeMeta(f'dataset-{experiment_run}',
|
2024-12-03 18:32:48 -03:00
|
|
|
announce_url=tracker.announce_url))
|
|
|
|
))
|
2024-11-28 09:46:21 -03:00
|
|
|
for experiment_run in range(self.repetitions)
|
2024-11-26 19:53:59 -03:00
|
|
|
)
|
2024-11-28 09:46:21 -03:00
|
|
|
|
|
|
|
return IteratedExperiment(repetitions)
|