Files
Tesi/Tesi.tex
Mirko Milovanovic b8df6b773c
All checks were successful
Build LaTeX Document / build_latex (push) Successful in 3m18s
feat: add introduction to PeerTube architecture and technologies chapter
2025-03-24 16:06:20 +01:00

1208 lines
78 KiB
TeX
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass[12pt,a4paper]{book} % o article, book, ...
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% packages...
\usepackage[utf8]{inputenc}
\usepackage[english, italian]{babel}
\usepackage[hyphens]{url}
%\usepackage{showframe}
% Per generare il file PDF aderente alle specifiche PDF/A-1b. Verificarne poi la validità.
\usepackage{colorprofiles}
\usepackage[a-2b,mathxmp]{pdfx}
\usepackage{hyperref}
\hypersetup{
colorlinks,
linkcolor={black!100!black},
citecolor={blue!100!black},
urlcolor={blue!100!black}
}
\usepackage{biblatex}
\bibliography{Biblio.bib}
\usepackage{graphicx}
\usepackage{geometry}
\usepackage{tabularx}
\usepackage{booktabs}
\usepackage{float}
\usepackage{caption}
\captionsetup[figure]{labelsep=period}
\usepackage{lipsum} % Per inserire testo a caso in attesa di realizzare i capitoli
\usepackage{listings} % Per inserire codice formattato
%\usepackage{minted}
%\lstset{
%lstset va usato dopo l'inizio del document e ogni volta che si vuole cambiare/impostare il linguaggio da formattare
% language=bash
%frame=single,
%breaklines=true,
%postbreak=\raisebox{0ex}[0ex][0ex]{\ensuremath{\color{red}\hookrightarrow\space}},
%basicstyle=\ttfamily\footnotesize
%}
\usepackage{csquotes}
\usepackage{epigraph} % per le frasi inizio capitolo
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhead[LEO]{\slshape \leftmark} %section
\fancyhead[REO]{\thepage}
\setlength{\headheight}{14.5pt}
%\usepackage{etoolbox}
\usepackage[italian, textsize=tiny]{todonotes}
\setlength{\marginparwidth}{2cm}
%\usepackage{refcheck}
\usepackage{tikz}
\usetikzlibrary{arrows}
\usepackage{titlesec}
\newenvironment{usecaseenv}{
\def\arraystretch{2}
\begin{tabular}{p{3cm}p{10cm}}\hline
}{
\hline\end{tabular}
\def\arraystretch{1}
}
\newenvironment{characteristicsEnv}{
\def\arraystretch{2}
\begin{tabular}{lp{8cm}}\hline
}{
\hline\end{tabular}
\def\arraystretch{1}
}
\newcommand\addheading[1]{
\multicolumn{2}{c}{\textbf{\textit{#1}}}\\ \hline
}
\newcommand\addrow[2]{
\textbf{#1}
&\begin{minipage}[t][][t]{10cm}
#2
\end{minipage}\\
}
\newcommand\addrowservice[2]{
\textbf{#1}
&\begin{minipage}[t][][t]{8cm}
#2
\end{minipage}\\
}
% The actual command definition
\let\oldFigureName\figurename %save the old definition of the caption's figure name
\newcommand{\usecase}[5]{
\vspace*{0.5cm} % adds a bit of padding to make it look nicer
\renewcommand{\figurename}{Use case} %call figure name "Use case" instead
\begin{figure}[htbp]
\begin{center}
\begin{usecaseenv}
\addheading{#1}
\addrow{Use case:}{#2}
\addrow{Soggetti:}{#3}
\addrow{Obiettivi:}{#4}
\end{usecaseenv}
\end{center}
\caption{#5}
\end{figure}
\renewcommand{\figurename}{\oldFigureName} %reset caption figure name
}
\let\oldFigureName\figurename %save the old definition of the caption's figure name
\newcommand{\serviceCharacteristics}[6]{
\vspace*{0.5cm} % adds a bit of padding to make it look nicer
\renewcommand{\figurename}{} %call figure name "Use case" instead
\begin{figure}[H]
\begin{center}
\begin{characteristicsEnv}
\addheading{Caratteristiche}
\addrowservice{Partecipanti:}{#1}
\addrowservice{Architettura software:}{#2}
\addrowservice{Architettura hardware:}{#3}
\addrowservice{Tipo di dato condiviso:}{#4}
\addrowservice{Licenza:}{#5}
\end{characteristicsEnv}
\end{center}
%\caption{}
\end{figure}
\renewcommand{\figurename}{\oldFigureName} %reset caption figure name
}
\raggedbottom
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\newgeometry{centering}
% Frontespizio
\pagenumbering{Roman}
\begin{titlepage}
\begin{center}
\includegraphics[width=\textwidth]{images/Logo.jpg}\\
{\large{\em Corso di Laurea in Informatica per la comunicazione digitale}}
\end{center}
\vspace{12mm}
\begin{center}
{\huge{\bf Streaming decentralizzato di}}\\
\vspace{4mm}
{\huge{\bf contenuti audiovisivi}}\\
\end{center}
\vspace{12mm}
\begin{flushleft}
{\large{\bf Relatore:}}
{\large{Trentini Andrea}}\\
%{\large{\bf Correlatore:}}
%{\large{...}}\\
\end{flushleft}
\vfill
\begin{flushright}
\parbox{1.7in}{
{\large{\bf Tesi di Laurea di:}}\\
{\large{Mirko Milovanovic}}\\
{\large{\bf Matricola: \normalfont 870671}}
}
\end{flushright}
\vfill
\begin{center}
{\large{\bf Anno Accademico 2024-2025}}
\end{center}
\end{titlepage}
\tableofcontents
\thispagestyle{empty}
\chapter{Introduzione}
\pagenumbering{arabic}
\setcounter{page}{1}
Fin dai suoi albori Internet, nato da ARPAnet, svolge un ruolo importantissimo nella vita di tutti noi, che sia condividere informazioni militari, utilizzare servizi erogati via Web, o più recentemente guardare contenuti audiovisivi ``on-the-go'', ovvero quello di connettere le persone intorno al globo nei più svariati modi possibili attraverso l'utilizzo di calcolatori come computer e/o dispositivi mobili ``connessi''.
Negli anni e per come è stato concepito Internet stesso architetturalmente, si sono venuti a formare veri metodi di comunicazione tra gli utilizzatori e gli erogatori di servizi Internet, più o meno sicuri, efficaci o resilienti rispetto a tematiche come la privacy dei dati, la centralizzazione e costi di operazione.
Il modello Client/Server è certamente il più diffuso, reso famoso dall'imponente World Wide Web, il modo più intuitivo di utilizzare Internet ma certamente non l'unico.\cite[]{w3c} Questa architettura, specialmente nell'ambito della trasmissione di contenuti audiovisivi in streaming, presenta notevoli sfide tecniche ed economiche. L'infrastruttura centralizzata richiede server potenti e costosi che devono gestire simultaneamente migliaia di connessioni, con un consumo di banda che cresce linearmente con il numero di spettatori.
Negli ultimi anni, diverse piattaforme hanno cercato di risolvere questo problema attraverso l'adozione di tecnologie peer-to-peer (P2P) per la distribuzione dei contenuti. Tra queste, PeerTube si distingue come una delle soluzioni più promettenti, combinando una struttura federata con tecnologie di streaming P2P che promettono di ridurre significativamente il carico sui server centrali.
Questa tesi si propone di analizzare criticamente le affermazioni fatte dagli sviluppatori di PeerTube riguardo l'efficienza e l'efficacia del loro approccio P2P nel contesto dello streaming video. Partiremo da un'analisi del panorama attuale dello streaming centralizzato, ne evidenzieremo i limiti, per poi esplorare le alternative decentralizzate e concentrarci su PeerTube, ricreando e ampliando i test condotti dai suoi sviluppatori per verificarne empiricamente le prestazioni.
\section{Il problema dello streaming centralizzato}
Un sistema Client/Server tradizionale per lo streaming video presenta diverse problematiche critiche:
\begin{itemize}
\item \textbf{Scalabilità limitata}: I server centrali devono gestire tutto il traffico in uscita, con costi di banda che crescono linearmente con il numero di spettatori.
\item \textbf{Single Point of Failure}: Se il server centrale subisce un'interruzione, tutti i client perdono l'accesso al servizio.
\item \textbf{Costi infrastrutturali elevati}: Mantenere server capaci di gestire picchi di traffico richiede investimenti significativi.
\item \textbf{Centralizzazione del controllo}: Poche entità controllano le piattaforme più popolari, con potenziali implicazioni per la libertà di espressione e la privacy.
\end{itemize}
\section{Le alternative decentralizzate e P2P}
Le tecnologie peer-to-peer offrono un approccio alternativo che potrebbe risolvere molti di questi problemi:
\begin{itemize}
\item \textbf{Distribuzione del carico}: Ogni client può anche fungere da distributore per altri client, riducendo il carico sul server originale.
\item \textbf{Maggiore resilienza}: L'assenza di un punto centrale di fallimento rende il sistema più robusto.
\item \textbf{Riduzione dei costi}: I costi di banda vengono distribuiti tra i partecipanti anziché essere sostenuti da un unico fornitore.
\item \textbf{Decentralizzazione del controllo}: Nessuna entità singola può controllare completamente il flusso di informazioni.
\end{itemize}
Tra le varie piattaforme che utilizzano questo approccio, PeerTube ha attirato la nostra attenzione per la sua architettura ibrida che combina federazione e P2P, e per le affermazioni dei suoi sviluppatori riguardo l'efficienza di questo approccio. In particolare, un articolo pubblicato dal team di PeerTube sostiene che la loro implementazione P2P può ridurre il carico sul server di origine fino all'80%, una cifra che merita un'analisi approfondita e una verifica indipendente.
\chapter{Stato dell'arte}
\epigraph{In questo capitolo analizzeremo il panorama attuale delle tecnologie di streaming, confrontando approcci centralizzati e decentralizzati per comprendere i loro punti di forza e debolezza.}{}
\section{Modelli di comunicazione in rete}
\subsection{Client/Server e il Web 2.0}
Un sistema Client/Server è un tipo di computazione distribuita in cui i clienti effettuano delle richieste verso un server che a sua volta risponde con i dati/servizi richiesti restando in attesa. I client possono essere di vario tipo e trovarsi ovunque nel globo e in generale integrano una parte hardware (smartphone, PCs, \dots) ad una software (applicazioni GUI, web browser, \dots). I server, invece, sono delle macchine specializzate spesso raggruppate assieme in grandi data center, interconnesse tra di loro per fornire uno o più servizi a molteplici client contemporaneamente.
\begin{figure}[H]
\centering
\includegraphics[scale=0.3]{images/client-server.png}
\caption{Modello Client/Server tradizionale}
\end{figure}
Questo modello ha dominato l'era del Web 2.0, caratterizzata da:
\begin{itemize}
\item Piattaforme centralizzate con contenuti generati dagli utenti
\item Elevata interattività e social networking
\item Controllo dei dati da parte delle grandi aziende tecnologiche
\item Monetizzazione tramite pubblicità e raccolta dati
\end{itemize}
Nonostante i vantaggi in termini di semplicità d'uso e accessibilità, questo modello ha portato a:
\begin{itemize}
\item Forte centralizzazione del potere da parte di poche "Big Tech"
\item Elevati costi di infrastruttura
\item Problemi di privacy e controllo dei dati personali
\item Vulnerabilità a censura e manipolazione dei contenuti
\end{itemize}
\subsection{Peer-to-Peer e Web 3.0}
Il modello peer-to-peer rappresenta un approccio alternativo in cui ogni nodo della rete può fungere sia da client che da server, eliminando la necessità di un'infrastruttura centralizzata. Questo modello è alla base di molte tecnologie del cosiddetto Web 3.0, caratterizzato da:
\begin{itemize}
\item Decentralizzazione del controllo e distribuzione del carico
\item Maggiore privacy e sovranità sui dati personali
\item Resilienza a censura e fallimenti di singoli nodi
\item Riduzione dei costi infrastrutturali
\end{itemize}
Tuttavia, le soluzioni P2P presentano anche alcune sfide:
\begin{itemize}
\item Maggiore complessità tecnica
\item Possibili problemi di latenza e qualità del servizio
\item Difficoltà nel garantire contenuti legali e moderazione
\item Sfide tecniche come il NAT traversal e la connettività tra peer
\end{itemize}
\break
\section{Casi d'uso per lo streaming decentralizzato}
Vediamo degli esempi di come questa interazione potrebbe essere svolta:
\usecase{Esempio d'interazione ``one to many''}{Un utente davanti al proprio computer vorrebbe condividere quello che vede sullo schermo con i propri amici o followers}{Utente principale, viewers, computer, connessione internet}{Condivisione in live streaming di un contenuto a schermo via internet con TCP/IP}{}
\usecase{Esempio d'interazione ``many to many''}{Più utenti al proprio computer vorrebbero comunicare e interagire tra di loro contemporaneamente simil conference-call}{Utenti multipli, computer, connessione internet, microfono, telecamera}{Live streaming e interazione real-time tra utenti via internet con TCP/IP}{}
\usecase{Esempio d'interazione ``one to many''}{Unazienda per questioni legate alla sicurezza sul lavoro si ritrova con la necessitò di dover fare dei ``workshop'' in diretta ai propri dipendenti con diverse locazioni sparse per il nel mondo senza utilizzare però grandi servizi cloud dato lelevato costo di banda e di noleggio del servizio per singolo utente finale, in questo caso il singolo dipendente}{Dipendenti, azienda}{Video streaming dei ``workshop'' per i dipendenti sparsi per il mondo}{}
\usecase{Esempio d'interazione ``one to many''}{Un gruppo di amici deve svolgere un progetto universitario assieme e quindi interagire tra di loro facendo pair programming condividendo lo schermo gli uni con gli altri. Per questioni di privacy e sicurezza non vuole utilizzare un servizio pubblico come Discord in quanto vorrebbero tenere tutto segreto fino al giorno della presentazione}{Studenti}{Pair programming}{}
\usecase{Esempio d'interazione ``one to many''}{Una casa produttrice di film emergente vuole condividere i nuovi film in produzione con dei trailer ma a causa di dispute legate ai DRM, copyright e content strike di altre aziende più grandi non vuole utilizzare dei servizi già esistenti con EULA molto restringenti ma vuole avere il controllo dei propri diritti sul contenuto creato da essa stessa}{Filmmakers, appassionati di film}{Condivisione degli ultimi trailer per i film prodotti dalla casa}{}
\usecase{Esempio d'interazione ``one to many''}{Un gruppo di amici vuole fare una serata di gioco online e vuole condividere il proprio schermo con gli altri giocatori per poter giocare assieme}{Gamer}{Condivisione dello schermo per giocare assieme}{}
\break
In sintesi, l'analisi dei casi d'uso evidenzia la necessità di una soluzione di streaming decentralizzata e a licenza libera, capace di operare in modalità uno-a-molti o molti-a-molti, senza affidarsi a servizi cloud proprietari e senza richiedere il deploy di una complessa infrastruttura hardware globale. I requisiti fondamentali, soprattutto in relazione all'elevato fabbisogno di banda tipico dei contenuti video, si declinano nei seguenti scenari applicativi:
\hfill\break
\textbf{Commerciale:}
\begin{itemize}
\item Streaming di eventi o riunioni interne,
\item Assistenza remota,
\item Conference calls,
\item Possibilità di operare sia come utente che come provider/distributore,
\item Ottimizzazione dei costi e del consumo della banda.
\end{itemize}
\hfill\break
\textbf{Educazionale:}
\begin{itemize}
\item Trasmissione in diretta di corsi e lezioni.
\end{itemize}
\hfill\break
\textbf{Sociale:}
\begin{itemize}
\item Organizzazione di lan party,
\item Supporto per streaming di gaming e attività live da parte di streamer,
\item Conference calls in piccoli gruppi,
\item Impiego per telecamere di sicurezza,
\item Moderazione dei contenuti online.
\end{itemize}
\hfill\break
\textbf{Istituzionale:}
\begin{itemize}
\item Comunicazioni video in situazioni di emergenza.
\end{itemize}
\section{Panoramica delle piattaforme di streaming esistenti}
\subsection{Soluzioni centralizzate}
\subsubsection{Twitch}
Twitch è una piattaforma di live streaming di proprietà di Amazon lanciata nel 2011, originariamente specializzata nella trasmissione in diretta di videogiochi, eSports ed eventi riguardanti il mondo videoludico.
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{images/twitchHome.png}
\caption{Home page di Twitch.}
\end{figure}
Una delle più famose e grandi, la piattaforma è stata originariamente sviluppata come una controparte di streaming per Justin.tv, una piattaforma di streaming generale. Tuttavia, Twitch si è concentrata esclusivamente sui contenuti di videogiochi e di eSports, anche se oggi rimane tutt'ora la scelta "de-facto" per molti utenti non solo per lo streaming di contenuti videoludici ma anche per lo "streaming general purpose" come ad esempio lo streaming di musica, arte, cucina e di varie attività creative.
Negli anni successivi, ha visto una rapida crescita e ha attirato una vasta gamma di creatori di contenuti, dalle grandi organizzazioni di esports ai singoli streamer indipendenti, fino ad oggi con una user base di circa 3 milioni di viewers e 1.5 milioni di broadcaster giornalieri rispettivamente.
Twitch offre molti servizi sotto un unico sito web accessibile con un semplice browser:
\serviceCharacteristics{Chiunque con un account può condividere e guardare}
{Centralizzata}
{Servizio accessibile via browser o applicazione mobile}
{Stream video e testo per funzionalità di live chat}
{Proprietaria con contratto di utilizzo `EULA'}
\subsubsection{YouTube}
Youtube è una piattaforma di sharing online di video statici, di proprietà di Google, specializzata nella condivisione globale di video generici con funzionalità aggiuntive di social media, monetizzazione e live streaming.
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{images/youtubeHome.png}
\caption{Home page di Youtube.}
\end{figure}
La compagnia è stata lanciata nel febbraio 2005 come indipendente ed è poi stata successivamente acquisita da Google. Al momento viene considerata la piattaforma più grande e longeva di questo segmento, con più di 2.5 miliardi di utenti mensili e milioni di ore di video condivisi ogni giorno. Dall'acquisizione, YouTube ha espanso la propria offerta al di fuori della sola condivisione di video "amatoriali", includendo contenuti come film di produzione professionale, video musicali ufficiali, documentari, news, ecc. Ha anche integrato la piattaforma pubblicitaria AdSense, sempre di proprietà di Google, permettendo a tutti gli utenti amatoriali o professionali approvati di poter ricevere un ricavo economico dalle pubblicità e dal marketing presenti sul sito.
\serviceCharacteristics{Chiunque sul web}{Servizio accessibile via browser o applicazione mobile}{Centralizzata con utilizzo di CDN}{Video statici, live stream}{Proprietaria con contratto di utilizzo `EULA'}
\subsection{Soluzioni decentralizzate e P2P}
\subsubsection{Tahoe-LAFS}
Tahoe-LAFS è un sistema di file distribuito, open source, decentralizzato e sicuro che permette agli utenti di memorizzare e condividere file in un ambiente di rete distribuita chiamata `Grid'. Sviluppato da un gruppo di ricercatori dell'Università di Maryland, dal 2007 ed è stato rilasciato come software open source sotto licenza GPL. Tahoe-LAFS è stato progettato per essere un sistema di file distribuito sicuro, affidabile e scalabile, in modo da poter essere utilizzato in ambienti di rete distribuita, dato che promette di essere un sistema `provider-independent', ovvero che i fornitori dei server intermediari non hanno mai la possibilità di accedere o modificare i dati memorizzati dagli utenti finali perché che non sono loro a garantire la confidenzialità, l'integrità o l'assoluta disponibilità dei dati, ma sono i client finali a farlo.
Alla base, Tahoe-LAFS è essenzialmente un sistema di archiviazione chiave-valore. L'archivio utilizza delle corte stringhe, circa 100 byte, chiamate `capabilities' come chiavi e dati arbitrari come valori.
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{images/tahoe-LAFS.logo.png}
\caption{Tahoe-LAFS logo.}
\end{figure}
Si possono condividere queste `capabilities' per dare agli altri accesso a determinati valori sulla `Grid'. Ad esempio, si può dare la possibilità di lettura ad un amico e conservare il permesso di scrittura per te stessi.
Per eliminare un valore, basta dimenticare (cioè eliminare) la chiave della `capability', e, una volta fatto sarà impossibile recuperare i dati. I server di archiviazione però hanno un modo per fare `garbage-collection' da condivisioni non referenziate.
In aggiunta al sistema chiave-valore, viene affiancato un livello i file-storage classico, che consente di condividere, con altri utenti, sotto-directory senza, ad esempio, rivelare l'esistenza o il contenuto delle directory principali.
Come detto prima, sono i clienti a garantire l'integrità e la confidenzialità dei dati, e questo viene realizzato grazie alla crittografia che viene eseguita su ogni `capability' prima di essere caricata sul `Grid'. Ogni valore viene prima crittografato con una chiave asimmetrica e poi spezzettato in parti più piccole, e più maneggiabili. Questi segmenti diventano poi effettivamente gli `share' che verranno memorizzati nei noti della rete, che ricordiamo, svolgono solo la funzione di memorizzazione dei dati, gli utenti non si affidano a loro per altro. \cite{tahoelafsAbouttahoerstTrunkdocs} \cite{torprojectHeartTahoeLAFS}
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{images/tahoe-simple-data-flow.png}
\caption{Tahoe-LAFS simple data flow.}
\end{figure}
\serviceCharacteristics{Utenti e server di terze parti}{Software client lato utente}{Decentralizzata e `provider-indipendent'}{Qualsiasi tipo di file binario}{GPL}
\subsubsection{IPFS}
IPFS o `InterPlanetary File System' è una suite di protocolli e librerie open source per la condivisione di file in un ambiente di rete distribuita utilizzando meccanismi di `content-addressing'. IPFS è stato sviluppato da Protocol Labs, un'azienda di ricerca e sviluppo nel 2014.
IPFS punta a creare un file system condiviso da una rete di nodi decentralizzata che comunica attraverso P2P, dove i singoli file sono organizzati come blocchi indipendentemente individuabili ed immutabili (ovvero che non possono essere modificati ma solo aggiunti o eliminati) con degli identificatori chiamati `CID (Content identifiers)' memorizzati in un database distribuito chiamato `DHT (Distributed Hash Table)' che viene condiviso con ogni singolo nodo della rete al fine di facilitare il routing dei dati attraverso essa stessa.
Uno dei problemi di IPFS è che per design stesso, ogni singolo file è visibile a tutti i nodi della rete e quindi non è possibile creare un sistema di condivisione di file privati, ma solo di file pubblici, che però volendo possono essere crittografati, impedendo la lettura dei dati da parte di attori terzi. \cite{ipfsWhatIPFS} \cite{ipfsIPFSWhitepaper}
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{images/Data-sharing-on-IPFS-by-owner.png}
\caption{IPFS data flow. \cite{ResearchBasedDataRightsManagementUsingBlockchainOverEthereumNetwork}}
\end{figure}
\serviceCharacteristics{Nodi della rete}{Protocolli e software lato client}{Decentralizzata simil Blockchain}{Qualsiasi tipo di file binario}{MIT}
\subsubsection{PeerTube}
PeerTube è un servizio di video sharing open source, federalizzato e decentralizzato (lato client), basato su protocolli peer-to-peer come `WebTorrent', `WebRTC' e altre tecnologie web standard.
Fa parte del cosiddetto `Fediverse', un insieme di server interconnessi che comunicano tramite ActivityPub, un protocollo di comunicazione aperto per creare reti federate.
Inizialmente creato come una piattaforma di video sharing per i creatori di contenuti indipendenti, è stato progettato per essere estensibile e adattabile a qualsiasi tipo di contenuto video che rispetti i termini delle singole istanze che vengono messe a disposizione pubblicamente.
Il funzionamento è del tutto simile ad altre piattaforme video tipo (YouTube, Vimeo, Dailymotion, ecc.) con supporto per video statici e livestream, ma con la differenza che i video possono essere memorizzati e condivisi non solo dalle singole istanze della federazione attraverso il normale HTTP ma anche tra i client finali usando P2P per alleggerire il carico di banda.
PeerTube è iniziato come progetto indipendente da un singolo sviluppatore che poi è stato affiancato dalla no-profit Framasoft. \cite{peertubeAbout} \cite{wiki:ActivityPub} \cite{activitypubActivityPubRocks}
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{images/peerTubeHome.png}
\caption{PeerTube.}
\end{figure}
\serviceCharacteristics{Utenti registrati e non delle singole istanze}{Browser web e server indipendenti}{Federalizzata e decentralizzata P2P}{Video statici e livestream}{AGPLv3+}
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{images/peerTubeItalia.png}
\caption{Una istanza di PeerTube Italiana.}
\end{figure}
\subsubsection{Ace Stream}
Ace Stream è un software proprietario di video streaming basato su P2P, sviluppato da un gruppo di sviluppatori russi, che permette agli utenti di trasmettere in diretta video e audio, riprodurre file multimediali, e ricevere e condividere contenuti in tempo reale. Il software è stato rilasciato per la prima volta nel 2013 e da allora è stato scaricato più di 100 milioni di volte. Ace Stream offre una vasta gamma di funzionalità che lo rendono popolare tra gli utenti che desiderano guardare contenuti in streaming. Utilizzando la tecnologia P2P, il software consente agli utenti di trasmettere video e audio in tempo reale, senza dover attendere il completamento del download. Questo significa che gli utenti possono godere di una riproduzione fluida e senza interruzioni, anche con connessioni internet più lente.
\begin{figure}[htb]
\centering
\includegraphics[width=\textwidth]{images/Ace_Stream_logo.png}
\caption{PeerTube.}
\end{figure}
Inoltre, Ace Stream supporta la riproduzione di file multimediali locali, consentendo agli utenti di guardare i propri film, serie TV e altri contenuti salvati sul proprio dispositivo. Il software supporta una vasta gamma di formati video e audio, garantendo un'alta compatibilità.
Un'altra caratteristica interessante di Ace Stream è la possibilità di ricevere e condividere contenuti in tempo reale. Gli utenti possono creare i propri canali di streaming e condividere i propri contenuti con altri utenti. Questo rende il software ideale per gli appassionati di sport, che possono trasmettere eventi sportivi in diretta e condividerli con altri appassionati.
Ace Stream è disponibile per diverse piattaforme, tra cui Windows, Mac, Linux e Android, il che lo rende accessibile a un vasto pubblico. Inoltre, il software è gratuito da scaricare e utilizzare, rendendolo ancora più attraente per gli utenti.
In conclusione, Ace Stream è un software potente e versatile per lo streaming di video e audio. Grazie alla sua tecnologia P2P, offre una riproduzione fluida e senza interruzioni, consentendo agli utenti di godersi i propri contenuti preferiti in tempo reale. Con la possibilità di condividere contenuti e creare canali di streaming, Ace Stream offre un'esperienza di streaming interattiva e coinvolgente. \cite{acestreamAnnouncementStream} \cite{archiveStream}
\serviceCharacteristics{Utenti registrati e non delle singole istanze}{Browser web e server indipendenti}{Federalizzata e decentralizzata P2P}{Video statici e livestream}{AGPLv3+}
\chapter{PeerTube: architettura e tecnologie}
Tra tutti i progetti open source che si occupano di decentralizzazione e P2P, PeerTube è uno dei più interessanti e promettenti. In questo capitolo, esamineremo l'architettura e le tecnologie alla base di PeerTube, analizzando come il progetto si è evoluto nel corso degli anni e quali sono le sue caratteristiche principali.
\section{Storia e evoluzione del progetto}
PeerTube è nato nel 2017 come progetto dell'organizzazione non profit francese Framasoft, con l'obiettivo di creare un'alternativa libera e decentralizzata a piattaforme come YouTube. Da allora, ha visto una crescita costante sia in termini di funzionalità che di adozione, con oltre 1000 istanze attive in tutto il mondo nel 2023.
Le principali tappe evolutive del progetto includono:
\begin{itemize}
\item 2017: Prima versione beta con supporto per video statici
\item 2018: Rilascio della versione 1.0 con supporto per la federazione via ActivityPub
\item 2019: Introduzione del supporto per lo streaming live
\item 2020-2021: Miglioramenti dell'interfaccia utente e del sistema di raccomandazione
\item 2022: Ottimizzazione del protocollo P2P e introduzione di OpenTelemetry per il monitoraggio
\item 2023: Rilascio della versione 6.0 con significative migliorie al sistema P2P
\end{itemize}
\section{Stack tecnologico}
\subsection{Architettura generale}
PeerTube utilizza un'architettura ibrida che combina:
\begin{itemize}
\item Un backend basato su Node.js e TypeScript
\item Un frontend realizzato con Angular
\item Un sistema di storage per i video (locale o distribuito)
\item Un database PostgreSQL per la persistenza dei dati
\item Un sistema di federazione basato su ActivityPub
\item Tecnologie P2P per la distribuzione dei contenuti
\end{itemize}
\subsection{Streaming video con HLS}
Per lo streaming video, PeerTube utilizza il protocollo HTTP Live Streaming (HLS), sviluppato da Apple. Questo protocollo:
\begin{itemize}
\item Divide il video in piccoli segmenti (tipicamente di 2-10 secondi)
\item Crea un file manifest (.m3u8) che elenca i segmenti disponibili
\item Permette la selezione automatica della qualità in base alla connessione
\item È compatibile con la maggior parte dei browser e dispositivi moderni
\end{itemize}
\subsection{P2P Media Loader e WebRTC}
Il cuore del sistema P2P di PeerTube è costituito da:
\begin{itemize}
\item \textbf{P2P Media Loader}: Una libreria JavaScript che integra il P2P nel player video
\item \textbf{WebRTC}: Una tecnologia standard per la comunicazione peer-to-peer diretta tra browser
\item \textbf{WebTorrent Tracker}: Utilizzato come sistema di signaling per connettere i peer
\end{itemize}
\section{Signaling e NAT Traversal}
Un aspetto critico del sistema P2P è il processo di signaling, che permette ai peer di scoprirsi e connettersi tra loro. PeerTube utilizza:
\begin{itemize}
\item \textbf{WebTorrent Tracker}: Per la scoperta dei peer che stanno guardando lo stesso contenuto
\item \textbf{Server STUN}: Per facilitare il NAT traversal, permettendo ai peer di stabilire connessioni anche quando si trovano dietro router NAT
\item \textbf{Server TURN} (opzionale): Come fallback quando la connessione diretta non è possibile
\end{itemize}
\section{Algoritmo di selezione dei peer}
L'efficienza del sistema P2P dipende in modo cruciale dall'algoritmo utilizzato per selezionare i peer da cui scaricare i dati. PeerTube utilizza un algoritmo simile a quello di BitTorrent, che considera:
\begin{itemize}
\item \textbf{Disponibilità dei segmenti}: Priorità ai peer che hanno i segmenti richiesti
\item \textbf{Velocità di download}: Preferenza per i peer che offrono migliori prestazioni
\item \textbf{Rarità dei segmenti}: Priorità allo scaricamento dei segmenti meno diffusi nella rete
\item \textbf{Reciprocità}: Tendenza a favorire i peer che a loro volta condividono dati
\end{itemize}
\section{Sistema di monitoraggio integrato con OpenTelemetry}
PeerTube integra OpenTelemetry per il monitoraggio delle prestazioni del sistema P2P, raccogliendo metriche come:
\begin{itemize}
\item \textbf{Percentuale di dati condivisi via P2P}
\item \textbf{Numero di peer connessi}
\item \textbf{Latenza delle connessioni}
\item \textbf{Utilizzo della banda del server}
\item \textbf{Errori e disconnessioni}
\end{itemize}
Queste metriche possono essere visualizzate attraverso dashboard Grafana o altri sistemi di monitoraggio compatibili con OpenTelemetry.
\chapter{Verifica empirica delle prestazioni P2P di PeerTube}
A dicembre 2023, il team di PeerTube ha pubblicato un articolo in cui va ad analizzarne le prestazioni facendo degli \textit{stress test} per verificare se la tecnologia P2P integrata nel sistema sia effettivamente in grado di ridurre il carico sui server con circa 1000 utenti connessi contemporaneamente, in quanto, secondo i dati raccolti da Twitch nel 2022, coprivano il 99\% dei casi di utilizzo della piattaforma.
\
Per realizzare test veritieri, il team ha simulato 1.000 spettatori simultanei utilizzando 1.000 browser Chrome, ciascuno con un indirizzo IP pubblico IPv6 dedicato. Questo è stato realizzato tramite Selenium grid, un software di automazione e testing per i browser, affiancato da Docker su cloud Hetzner e successivamente con un potente server fornito da Octopuce.
La scelta di 1.000 spettatori è significativa poiché copre la stragrande maggioranza delle dirette streaming su piattaforme importanti come Twitch, suggerendo che PeerTube può essere adeguato per un'ampia gamma di casi d'uso.
In condizioni ottimali, l'aspetto P2P di PeerTube dovrebbe ridurre la larghezza di banda necessaria per trasmettere un video in diretta di un fattore da 3 a 4, standa quanto detto degli sviluppatori di PeerTube.
\
Sono stati condotti 4 scenari di test principali:
\begin{itemize}
\item Live streaming con impostazione \textit{Normal Latency}
\item Live streaming con impostazione \textit{High Latency}
\item Live streaming con impostazione \textit{High Latency} e 50\% dei peer con P2P disabilitato
\item Un normale video \textit{on-demand}
\end{itemize}
su una macchina virtuale con:
\begin{itemize}
\item 4 vCore i7-8700 CPU @ 3.20GHz
\item 4 GB di RAM
\item 1 Gbps di banda
\end{itemize}
I dati dei test sono stati raccolti tramite OpenTelemetry e Grafana, con metriche come:
\begin{itemize}
\item Percentuale di dati trasferiti via P2P vs. dal server
\item Utilizzo di CPU
\item Comportamento in condizioni di rete variabili
\item Numero di spettatori
\end{itemize}
con i quali, infine, sono stati in grado di dimostrare che PeerTube è in grado di gestire 1.000 spettatori simultanei con un carico minimo sui server, grazie alla tecnologia P2P integrata in quanto la quantità di dati trasferiti via P2P, è progressivamente aumentata con il tempo, fino a raggiungere un rapporto del 75\% dei dati totali trasferiti per i video in diretta e del 98\% per i video \textit{on-demand}.
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{images/chrome_Mqt9TamrBT.png}
\caption{PeerTube conclusioni sullo stress test.}
\end{figure}
Tuttavia, l'articolo non fornisce dettagli sufficienti sulla metodologia utilizzata né rilascia gli strumenti specifici per riprodurre i test in modo indipendente. \cite{joinpeertubePeerTubeStress}
\
Perciò abbiamo deciso di creare un sistema di test automatizzato che possa riprodurre i test descritti nell'articolo originale.
\section{Metodologia per la verifica empirica}
Per verificare le affermazioni degli sviluppatori di PeerTube, abbiamo deciso di:
\begin{itemize}
\item Creare un'automazione per riprodurre indipendentemente i test descritti nell'articolo
\item Raccogliere metriche più dettagliate rispetto a quelle presentate nell'articolo originale
\item Analizzare i dati raccolti per valutare le prestazioni del sistema P2P di PeerTube
\end{itemize}
\section{Stack tecnologico per i test}
Per i nostri test abbiamo utilizzato una combinazione di tecnologie open source per creare un sistema di test automatizzato che sfrutta le seguenti tecnologie:
\begin{itemize}
\item \textbf{Docker}: Per creare ambienti isolati e facilmente riproducibili
\item \textbf{Telegraf}: Per la raccolta di metriche di sistema e di rete
\item \textbf{MongoDB}: Per l'archiviazione strutturata dei dati raccolti
\item \textbf{Python}: Come linguaggio principale per l'automazione
\item \textbf{Selenium}: Per simulare browser reali che guardano lo stream
\item \textbf{WebRTC Internals Exporter}: Una estensione del browser creata per raccogliere metriche dettagliate sulle connessioni WebRTC
\item \textbf{WebPack}: Un sistema di compilazione e gestione delle dipendenze per il frontend web
\item \textbf{Hetzner Cloud e script CLI}: Per distribuire i test su macchine virtuali in diverse regioni geografiche
\end{itemize}
\subsection{Docker}
Docker è una piattaforma open source che semplifica la creazione, la distribuzione e l'esecuzione di applicazioni in contenitori. I contenitori Docker sono degli ambienti isolati che simulano un sistema operativo completo, come le macchine virtuali, consentendo di eseguire applicazioni in modo consistente su qualsiasi ambiente.
La differeneza tra docker e una macchina virtuale è che i container Docker condividono il kernel del sistema operativo host, riducendo l'overhead e migliorando le prestazioni, senza dover ricorrere ad un \footnote{Hypervisor: Software che consente di eseguire più sistemi operativi su singolo hardware.}\textit{Hypervisor} per la virtualizzazione.
\begin{figure}[H]
\centering
\includegraphics[width=350pt]{images/docker-engine.png}
\caption{Docker Engine.}
\end{figure}
In se Docker è composto da 4 componenti principali:
\begin{itemize}
\item \textbf{Docker Engine}: Il core del sistema, responsabile della creazione e gestione dei container nonché il pricesso demone eseguito sulla macchina host. Fornisce l'accesso a tutte le funzionalità e i
servizi messi a disposizione da Docker. Mette a disposizione un insieme di comandi per la gestione dei container, delle immagini e dei volumi.
\item \textbf{Docker Client}: Interfaccia da riga di comando e \footnote{API: sinonimo di Application Programming Interface.} \textit{API} per interagire con Docker Engine.
\item \textbf{Docker Image}: Un \textit{template} di sola lettura che contiene e definisce i parametri di una applicazione da eseguire in un container a runtime. Le immagini vengono create e organizzate per livelli \textit{stateless} e immutabil.
\item \textbf{Docker Container}: Un'istanza in esecuzione di un'immagine Docker. Un container è un ambiente isolato che esegue un'applicazione specifica e include tutto il necessario per eseguire l'applicazione, come il codice, le librerie, le variabili d'ambiente e le dipendenze. Il \textit{filesystem} del container è l'ultimo livello che viene aggiunto al quale vi è possibile accedere sia in lettura che in scrittura. I contenitori, inoltre, possono essere associati a dei volumi per la persistenza dei dati, i quali fornisono un metodo semplice e immediato per condivuidere dati tra i container e l'host.\\La comunicazione tra container avviene tramite la creazione di \textit{network} o reti separate che vengono connesse ai singoli container, abilitando così una sorta di LAN interna tra un insieme di container. Per far, invece, comunicare i container con il mondo esterno bisogna invece utilizzare i `port mapping' tra una porta della macchina host e una porta del container.
\end{itemize}
\begin{figure}[H]
\centering
\includegraphics[width=200pt]{images/0_ukWqRD74ltfb5Uaz.png}
\caption{Docker Overview.}
\end{figure}
Approfondendo il discorso del networking, Docker mette a disposizione varti tipi di reti per la comunicazione tra container, i 3 principali sono:
\begin{itemize}
\item \textbf{Bridge}: È la rete di default che viene creata quando si installa Docker. I container connessi a questa rete possono comunicare tra loro e con il host, ma non possono comunicare con i container in altre reti.
\item \textbf{Host}: I container connessi a questa rete, condividono la rete dell'host, quindi non hanno bisogno di fare \textit{port mapping} per comunicare con il mondo esterno.
\item \textbf{None}: I container connessi a questa rete non hanno accesso ad acluna rete, quindi non possono comunicare con altri container o con l'esterno.
\end{itemize}
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{images/Docker-network-1.png}
\caption{Docker Networking.}
\end{figure}
\cite{AzureFunctions} \cite{geeksforgeeksContainerizationUsing} \cite{geeksforgeeksDockerNetworking}
\subsection{Telegraf}
Telegraf è un agente di raccolta di metriche open source sviluppato da InfluxData. È progettato per raccogliere, elaborare e inviare metriche da una varietà di sorgenti, tra cui sistemi operativi, database, applicazioni e dispositivi di rete.
\begin{figure}[H]
\centering
\includegraphics[width=300pt]{images/telegraf-architecture-diagram.png}
\caption{Architettura Telegraf.}
\end{figure}
Scritto in \textit{Go}, Telegraf è dodato di oltre 300 plugin di input, trasformazione e output di dati, che consentono di raccogliere metriche da una vasta gamma di sorgenti. Per sua natura, funziona come un pipeline di dati che può essere instradata attraverso diversi plugin per elaborare e aggregare le informazioni prima di raggiungere l'output finale.
Alcuni componenti principali di Telegraf includono:
\begin{itemize}
\item \textbf{Agent}: Il core del sistema, responsabile della raccolta e dell'elaborazione delle metriche dai plugin di input definiti e le invia ai plugin di output specificati, in base alla configurazione fornita.
\item \textbf{Input Plugins}: Raccolgono metriche da sorgenti come sistemi operativi, database, applicazioni e dispositivi di rete.
\item \textbf{Processor Plugins}: Elaborano e trasformano le metriche raccolte prima di inviarle all'output.
\item \textbf{Output Plugins}: Inoltrano le metriche elaborate a un sistema di monitoraggio o di archiviazione.
\item \textbf{Aggregator Plugins}: Aggregano le metriche raccolte per ridurre il volume dei dati.
\end{itemize}
La configurazione di Telegraf è definita da un file di configurazione \textit{TOML} che definisce i plugin di input, processore e output da utilizzare, insieme a eventuali parametri aggiuntivi necessari per la raccolta e l'elaborazione delle metriche.
Viene spesso utilizzato affianco ad un database di tipo \textit{time-series} come InfluxDB per l'archiviazione e la visualizzazione delle metriche raccolte, ma può essere integrato con una vasta gamma di sistemi di monitoraggio e analisi dei dati.\\
Una metrica \textit{time-series} è una serie di dati indicizzati in sequenza rispetto al tempo. Un esempio è una sequenza di osservazioni o rilevazioni registrate allo scorrere del tempo. Vi sono due macrocategorie di \textit{time-series}:
\begin{itemize}
\item \textbf{univariate time series}: le osservazioni sono monodimensionali, ovvero: viene registrato un solo valore numerico allo scorrere del tempo.
\item \textbf{multivariate time series}: le osservazioni sono multidimensionali, ovvero, si registrano più valori numerici per un singolo istante di tempo.
\end{itemize}
Tipicamente, vengono viene rappresentate con una struttura dati che registri un timestamp, che può essere di qualche tipo specifico per date, oppure un intero, contenente uno \textit{Unix timestamp}; oltre a questo contiene dati addizionali, che nella versione più semplice possono essere un unico valore numerico, ovvero losservazione registrata allo scorrere del tempo.
\cite{githubGitHubInfluxdatatelegraf} \cite{noauthor_telegraf_nodate} \cite{aiknowTimeSeries}
\subsection{MongoDB}
MongoDB è un database \textit{NoSQL} open source, orientato ai documenti, sviluppato da MongoDB Inc. È progettato per essere flessibile, scalabile e ad alte prestazioni, consentendo di memorizzare e interrogare dati in modo efficiente.
Combina la capacità di scalare orizzontalmente con funzionalità come indici secondari, query per intervallo, ordinamento, aggregazioni e indici geospaziali.
Un database orientato ai documenti sostituisce il concetto di `riga' con un modello più flessibile, il `documento'. Grazie alla possibilità di includere documenti incorporati e array, lapproccio orientato ai documenti permette di rappresentare relazioni gerarchiche complesse all'interno di un singolo record.
Non ci sono schemi predefiniti: le chiavi e i valori di un documento non hanno tipi o dimensioni fisse. L'assenza di uno schema rigido rende più semplice aggiungere o rimuovere campi secondo necessità. In generale, questo accelera lo sviluppo, permettendo agli sviluppatori di iterare rapidamente e sperimentare con facilità rendendo possibile testare diversi modelli di dati e scegliere quello più adatto alle proprie esigenze.
MongoDB è progettato per essere un database generi co, quindi, oltre alle operazioni di interimento, lettura, aggiornamento e eliminazione dei dati (\textit{CRUD}), offre alcune funzionalità uniche in più, tra cui:
\begin{itemize}
\item \textbf{Indicizzazioni}: Indici di diversi tipi, tra cui indici singoli, composti, geospaziali e testuali. Gli indici possono essere creati per qualsiasi campo all'interno di un documento, consentendo di ottimizzare le query per le prestazioni.
\item \textbf{Aggregazioni}: Un'ampia gamma di operazioni di aggregazione, come \textit{group}, \textit{match}, \textit{project} e \textit{sort}, che consentono di eseguire query complesse e analisi dei dati direttamente nel database.
\item \textbf{Collezioni speciali}: Collezioni speciali come le collezioni\textit{time-series} e le collezioni \textit{time-to-live}, che semplificano la gestione di dati temporali e di dati che devono essere eliminati dopo un certo periodo di tempo come ad esempio le sessioni utente.
\end{itemize}
MongoDB memorizza i record di dati come documenti (nello specifigo documenti \textit{BSON}, ovvero una rappresentazione binaria di documenti in formato \textit{JSON}), che sono raggruppati in collezioni. Un database contiene una o più collezioni di documenti.
\begin{figure}[H]
\centering
\includegraphics[width=300pt]{images/crud-annotated-document.png}
\caption{Documento JSON.}
\end{figure}
\textit{JSON}, o JavaScript Object Notation, è un formato di scambio dati testuale, basato su una sintassi di oggetti JavaScript. È comunemente utilizzato per trasmettere dati strutturati su una rete, come ad esempio tra un server e un client web. Un \textit{documento JSON}, invece, è una collezione di campi e valori organizzata in un formato strutturato.
MongoDB Query Language, o \textit{MQL}, è il linguaggio di query utilizzato per interagire con un database MongoDB. MQL è simile a SQL, ma è progettato per lavorare con documenti JSON e collezioni di documenti, piuttosto che con tabelle e righe. Consente agli utenti di recuperare documenti che corrispondono a criteri specifici, eseguire aggregazioni, apportare aggiornamenti ai documenti ed effettuare cancellazioni di documenti. La sintassi di MQL è progettata per essere semplice e intuitiva. Permette agli utenti di specificare condizioni utilizzando operatori come \$eq (uguale), \$ne (diverso), \$gt (maggiore di), \$lt (minore di) e molti altri. È possibile anche utilizzare operatori `bitwise' come \$and, \$or e \$not per creare query complesse.
\begin{figure}[H]
\centering
\includegraphics[width=280pt]{images/mongodb-pipelines.png}
\caption{MongoDB Aggregation Pipeline.}
\end{figure}
Infine, il MongoDB Query Language Aggregation Framework, è un set di processi che trasforma i dati in strutture che possono essere utilizzate per l'analisi. L'aggregazione si basa su un concetto di \textit{pipeline}, in cui i documenti vengono passati attraverso una serie di fasi di trasformazione. Ogni fase della pipeline esegue un'operazione specifica sui documenti, come filtering, proiezione, ordinamento, raggruppamento e altro ancora. Le fasi della pipeline, possono essere quindi concatenate per creare query più complesse.\cite{10.5555/2544030} \cite{mongodbDocumentsMongoDB} \cite{knowiBestIntroduction}
\subsection{Python}
Python è un linguaggio di programmazione ad alto livello, interpretato, orientato agli oggetti e con semantica dinamica. È progettato per essere facile da leggere e scrivere, con una sintassi pulita e chiara che favorisce la leggibilità del codice. Python è noto per la sua facilità d'uso e la sua versatilità, che lo rendono adatto a una vasta gamma di applicazioni, dallo sviluppo web alla data science, all'automazione dei processi.
Essendo un linguaggio interpretato, Python non richiede una fase di compilazione, ma viene eseguito direttamente da un \textit{interpreter}. Questo lo rende particolarmente adatto per lo sviluppo rapido di applicazioni e per l'iterazione veloce durante lo sviluppo. Python è anche noto per la sua vasta libreria standard, che fornisce un'ampia gamma di moduli e pacchetti pronti all'uso per svolgere una varietà di compiti comuni e per auesto viene utilizzato spesso per fare `data science'.\cite{10.5555/1593511}
L'indentazione è parte fontamentale in quanto, a differenza di altri linguaggi di programmazione dove l'indentazione è solo una convenzione, in Python è obbligatoria e definisce la struttura del codice. Questo rende il codice più leggibile e coerente, ma richiede anche attenzione per mantenere una corretta struttura del codice.
\break
\lstset{language=Python}
\begin{lstlisting}[caption={Esempio di codice Python}, captionpos=b, basicstyle=\footnotesize]
import numpy as np
def incmatrix(genl1,genl2):
m = len(genl1)
n = len(genl2)
M = None #to become the incidence matrix
VT = np.zeros((n*m,1), int) #dummy variable
#compute the bitwise xor matrix
M1 = bitxormatrix(genl1)
M2 = np.triu(bitxormatrix(genl2),1)
for i in range(m-1):
for j in range(i+1, m):
[r,c] = np.where(M2 == M1[i,j])
for k in range(len(r)):
VT[(i)*n + r[k]] = 1;
VT[(i)*n + c[k]] = 1;
VT[(j)*n + r[k]] = 1;
VT[(j)*n + c[k]] = 1;
if M is None:
M = np.copy(VT)
else:
M = np.concatenate((M, VT), 1)
VT = np.zeros((n*m,1), int)
return M
\end{lstlisting}
\subsection{Selenium}
Selenium è un framework open-source ampiamente utilizzato per l'automazione dei browser web. Fornisce un insieme di strumenti e librerie che consentono a tester e sviluppatori di interagire con gli elementi di una pagina, simulare azioni dell'utente ed eseguire test automatizzati su applicazioni web.
Uno degli aspetti chiave di Selenium è la sua capacità di funzionare con diversi browser, garantendo la compatibilità cross-browser e permettendo l'esecuzione di test in ambienti differenti.
Supporta diversi browser popolari, tra cui Google Chrome, Mozilla Firefox, Microsoft Edge, Safari e Opera. Ogni browser è gestito tramite implementazioni specifiche di \textit{WebDriver}, che fungono da ponte tra Selenium e il browser.
\begin{figure}[H]
\centering
\includegraphics[width=350pt]{images/which-browser-supports-selenium-1.png}
\caption{Browser supportati da Selenium.}
\end{figure}
Utilizzando i WebDriver, sviluppatori e tester possono scrivere script di automazione nel loro linguaggio di programmazione preferito ed eseguirli su diversi browser. Selenium WebDriver offre un'API unificata che astrae le differenze tra i vari browser, consentendo un'automazione fluida e risultati di test coerenti.
Una volta costruiti i casi di test, i dati devono essere comunicati al driver del browser in qualche modo. In Selenium, questo avviene utilizzando il `JSON Wire Protocol' con HTTP come gestore della comunicazione.
Poiché la comunicazione avviene in un'infrastruttura client-server, nel mondo di Selenium WebDriver questo sistema è noto come \textit{request-response} o \textit{command-response}.
\begin{figure}[H]
\centering
\includegraphics[width=300pt]{images/JSON-Wire-Protocol-over-HTTP-Client.png}
\caption{JSON Wire Protocol.}
\end{figure}
Il funzionamento dei WebDriver può essere riassunto in alcuni passaggi chiave:
\begin{itemize}
\item Un tester scrive uno script di test automatizzato destinato a un driver di browser specifico.
\item Quando viene premuto il pulsante `Esegui', lo script viene convertito in formato API con dati in JSON.
\item I dati vengono trasferiti al driver del browser utilizzando il JSON Wire Protocol su una rete HTTP come API RESTful.
\item Il driver del browser riceve i dati e, se la validazione ha successo, comunica le azioni al browser tramite HTTP.
\item Se la validazione fallisce, gli errori vengono restituiti al client.
\item Una volta avviato il browser, il driver esegue le azioni una per una, simulando il comportamento di un tester manuale attraverso l'automazione.
\item I comandi vengono inviati tramite HTTP, e le risposte vengono ricevute dallo stesso protocollo nel driver.
\item Dopo l'esecuzione di tutte le azioni, il browser si chiude e il driver comunica i risultati al client.
\end{itemize}
Affinché il driver possa comunicare correttamente con il browser, è fondamentale che il browser stessso sia installato sul sistema, e che il sistema e il suo ambiente sia configurato correttamente, con tutti i prerequisiti necessari per l'esecuzione dei test.
Un altro componente messo a dispoizione da Selenium è, \textit{Selenium Grid}, che permette di eseguire test su più macchine e browser remoti contemporaneamente, riducendo i tempi di esecuzione e migliorando l'efficienza dei test, instradando i comandi inviati dal client alle istanze remote dei browser ed è composto da 2 componenti principali:
\begin{itemize}
\item \textbf{Hub}: Il server principale che funge da punto di ingresso per i test. Riceve i comandi dai client e li instrada alle istanze dei browser remote.
\item \textbf{Node}: Le macchine remote che eseguono i test. Si connettono al \textit{Hub} e ricevono i comandi per eseguire i test sui browser installati.
\end{itemize}
\begin{figure}[H]
\centering
\includegraphics[width=300pt]{images/selenium-grid.jpg}
\caption{Architettura Selenium Grid.}
\end{figure}
Per fare tutto questo, Selenium mette a disposizione varie immagini Docker preconfigurate con tutto il necessario per eseguire i test, come il browser, il driver, l'hub, e le dipendenze necessarie, con anche diverse versioni legacy per testare la compatibilità con versioni obsolete.
In particolare, a noi interessa l'immagine \textit{selenium/standalone-chrome}, che contiene tutto il necessario per eseguire test su Chromium, incluso il browser stesso, il driver e il server Selenium, ed è stata usata come base per \textbf{creare una immagine Docker monolitica} per i nostri test, che include tutte le ulteriori dipendenze necessarie come:
\begin{itemize}
\item \textbf{Python}: Per l'automazione.
\item \textbf{Telegraf}: Per la raccolta ed invidio di tutte le metriche.
\item \textbf{WebRTC Internals Exporter}: Per la raccolta delle metriche WebRTC.
\item \textbf{Webpack}: Per la sostituzione delle variabili d'ambiente nel codice JavaScript.
\end{itemize} \cite{TestGrid_2024} \cite{scalerWhichBrowser} \cite{seleniumSeleniumBrowser}
\subsection{WebRTC Internals Exporter}
WebRTC Internals Exporter è un'estensione per Chromium che consente di esportare le metriche WebRTC da un browser in un formato leggibile e analizzabile. Creato da un ricercatore Italiano, è stato progettato per semplificare il processo di raccolta e analisi delle metriche WebRTC, che altrimenti sarebbero difficili da ottenere in quanto Chromium mette a disposizione uno strumento chiamato WebRTC-internals, che consente di visualizzare le statistiche WebRTC in tempo reale, ma non offre un modo semplice per esportarle dato che di base offre solo la creazione di file `dumps' non automatizzabile.
L'uso di webrtc-internals con il processo di creazione/caricamento dei dump presenta alcune grosse limitazioni:
\begin{itemize}
\item È necessario aprire la pagina \textit{chrome://webrtc-internals} prima di avviare una sessione. Se la sessione è già in corso e si verificano problemi, non è possibile raccogliere metriche retroattivamente.
\item La visualizzazione delle metriche è limitata nel tempo e non è possibile personalizzarle, filtrarle o creare query aggiuntive sui dati raccolti.
\item L'uso di file dump può rendere difficile l'archiviazione e l'organizzazione dei dati dei test, oltre alla condivisione dei risultati. Inoltre, il caricamento di file dump di grandi dimensioni in altri strumenti di analisi, potrebbe richiedere molto tempo e memoria.
\end{itemize}
\begin{figure}[H]
\centering
\includegraphics[width=300pt]{images/web-rtc-internals-chrome.png}
\caption{Grafici WebRTC Internals.}
\end{figure}
WebRTC Internals Exporter risolve questi problemi abilitando l'esportazione delle metriche verso un servizio chiamato \textit{Prometheus PushGateway}.
Prometheus PushGateway è un servizio progettato per permettere a lavori effimeri e batch di esporre le proprie metriche a Prometheus. Poiché questi processi potrebbero non esistere abbastanza a lungo da essere interrogati direttamente, possono invece inviare le loro metriche al PushGateway, garantendo così la raccolta dei dati.
Tecnicamente l'estensione funziona in questo modo: viene precaricato un codice JavaScript che sovrascrive la classe globale \textit{RTCPeerConnection}.
La nuova classe assegna un ID casuale a tutti gli oggetti peer connection creati e li memorizza all'interno dell'oggetto \textit{webrtcInternalExporter}. L'utente può abilitare l'estensione per la scheda attualmente aperta facendo clic sull'icona dell'estensione e attivando la relativa checkbox.
Dopo l'attivazione, lo script di override inizierà a chiamare periodicamente il metodo \textit{getStats} sugli oggetti creati. Tutte le metriche selezionate verranno inviate allo script in background, che le inoltrerà al servizio PushGateway configurato.
Il metodo \textit{getStats} è un metodo standardizzato definito nell'API WebRTC che consente di ottenere le statistiche relative a una connessione peer-to-peer.\cite{WebRTCDebugging}
\
Questo progetto fa uso di una \footnote{Disponibile qui: \url{https://gitea.kobim.cloud/kobim/peertube-collector/src/branch/main/webrtc-internals-exporter}} \textbf{versione altamente modificata} di WebRTC Internals Exporter, per adattarsi alle nostre esigenze di test e automazione. In particolare, abbiamo modificato le funzionalità:
\begin{itemize}
\item Abilitare l'esportazione delle metriche WebRTC verso un \textit{endpoint HTTP RESTful} al posto di Prometheus PushGateway, con una formattazione dei dati personalizzata, ma sempre basata su JSON.
\item Aggiunta di metriche esportate aggiuntive rispetto a quelle di base fornite da \textit{getStats}.
\item Abilitazione automatica dell'estensione all'avvio del browser, senza intervento manuale.
\item Supporto alla configurazione tramite variabili d'ambiente per semplificare l'integrazione con il nostro sistema di test.
\end{itemize}
\newpage
\begin{lstlisting}[caption={Esempio di dati JSON con le metriche esportate da WebRTC Internals Exporter}, captionpos=b, basicstyle=\scriptsize]
{
_id: ObjectId('67cf2a286904313f4e5ad32c'),
player: {
Codecs: {
Audio: 'mp4a.40.2',
Video: 'avc1.64002a'
},
'Connection Speed': {
Granularity: 's',
Speed: 16777216
},
'Download Breakdown': {
Peers: 0,
Server: 11534336
},
'Live Latency': {
Edge: 0,
Latency: 21
},
'Network Activity': {
Down: 7340032,
Up: 0
},
P2P: 'enabled',
'Player mode': 'p2p-media-loader',
Resolution: '1080p',
'Total Transfered': {
Down: 11534336,
Up: 0
},
'Video UUID': '70663bee-df65-4080-84bb-eefc5a11ab75',
...
},
peers: [
{
connectionState: 'new',
iceCandidateErrors: [
{
errorCode: 701,
errorText: 'STUN host lookup received error.',
timestamp: 1741629977060,
url: 'stun:stunserver2024.stunprotocol.org:3478'
},
...
],
iceCandidates: [
{
candidate: 'candidate:3130924284 1 udp 2113937151 172.17.0.2 43668...',
component: 'rtp',
foundation: '3130924284',
port: 43668,
priority: 2113937151,
protocol: 'udp',
relatedAddress: null,
relatedPort: null,
sdpMLineIndex: 0,
sdpMid: '0',
tcpType: null,
timestamp: 1741629977042,
type: 'host',
usernameFragment: '6V/z'
},
...
],
iceConnectionState: 'new',
iceGatheringState: 'complete',
id: '0dfd00af-518b-46c3-a2de-bc3330da9312',
signalingState: 'have-local-offer',
url: 'https://tube.kobim.cloud/w/eT1NZibmwMy6bx6N2YGLwr',
values: [
{
bytesReceived: 0,
bytesSent: 0,
id: 'D1',
label: '01e722a46bc1440994d511d27e86171d976d105a',
messagesReceived: 0,
messagesSent: 0,
protocol: '',
state: 'connecting',
timestamp: 1741629979445.746,
type: 'data-channel'
},
...
]
}
],
tags: {
host: 'selenium-nbg1-node-5-instance-1',
session: '64001538ac0eb86fafc5ed531b96ff7c',
url: 'https://tube.kobim.cloud/w/eT1NZibmwMy6bx6N2YGLwr'
},
timestamp: ISODate('2025-03-10T18:06:19.496Z')
}
\end{lstlisting}
\subsection{Webpack}
Webpack è un bundler di moduli per applicazioni JavaScript. Prende moduli con varie dipendenze e genera dei file statici che rappresentano quei moduli. È ampiamente utilizzato per applicazioni web moderne, in particolare quelle basate su framework come React, Angular e Vue.js.
Quando Webpack elabora un'applicazione, costruisce internamente un grafo delle dipendenze a partire da uno o più entry points. Successivamente, combina tutti i moduli necessari al progetto in uno o più bundle, che sono asset statici utilizzati per servire i contenuti dell'applicazione.
Di default, Webpack `comprende' solo file JavaScript e JSON.
Per gestire altri tipi di file, utilizza i \textit{Loaders}, che permettono di elaborare e convertire vari formati (come CSS, immagini o TypeScript) in altro moduli validi. Questi moduli possono essere quindi usati dall'applicazione ed aggiunti al grafo delle dipendenze.
Altro componente essenziale sono i \textit{Plugin}. Mentre i \textit{Loaders} trasformano i file in moduli validi, i \textit{Plugin} servono per eseguire operazioni più avanzate, come ottimizzazione, gestione degli asset, variabili dambiente e molto altro.\cite{webpackConceptsWebpack}
\subsection{Hetzner Cloud e script CLI}
Hetzner Cloud è un servizio di cloud computing offerto da Hetzner Online GmbH, un provider di servizi di hosting e data center con sede in Germania. Hetzner Cloud offre una vasta gamma di servizi di cloud computing, tra cui server virtuali, storage, reti e servizi di sicurezza.
Sulla base di quello che è stato fatto da PeerTube, abbiamo deciso di utilizzare Hetzner Cloud per distribuire i nostri test su macchine virtuali in diverse regioni geografiche, in quanto, gli script per l'automazione dei test sono l'unica parte fornitaci da PeerTube nell'articolo originale. Anche qua abbiamo utilizzato delle versioni altamente modificate per adattarle alle nostre esigenze.
Gli script fanno utilizzo della \footnote{CLI: sinonimo di Command-line interface} \textit{CLI}, di Hetzner Cloud, che consente di gestire le risorse cloud direttamente dalla riga di comando, e sono formati da 2 parti principali: uno script per la creazione delle macchine virtuali e uno script per l'avvio dei test.
Rispetto a quelli originali, li abbiamo modificati per far utilizzo delle varibili d'ambiente per la configurazione del nostro sistema di test, e per sostituire Selenium Grid, con l'immagine Docker monolitica standalone che abbiamo creato.\cite{githubGitHubHetznercloudcli} \cite{framagitFramasoftPeerTube}
\vfill \break
\section{Architettura del sistema di test}
Finora abbiamo descritto le tecnologie utilizzate alla base per creare il nostro sistema di test, senza però piegare effettivamente come queste vengono integrate e utilizzate insieme per creare un sistema di test automatizzato.
Introduciamo quindi l'ultimo pezzo necessario per far funzionare il tutto, ovvero il \textbf{\textit{collector}}, un'applicazione Python che si occupa di fare \footnote{Il data scraping è una tecnica in cui un programma informatico estrae dati da un output leggibile dall'uomo generato da un altro programma.} scraping delle metriche di PeerTube, di raccogliere le metriche WebRTC tramite l'estensione Chromium, e di inviare il tutto a Telegraf per l'elaborazione e l'invio al database.
\vfill
\begin{figure}[h]
\centering
\includegraphics[width=\textwidth]{images/mermaid-diagram-2025-03-22-144148.png}
\caption{Architettura del collector.}
\label{fig:architettura-collector}
\end{figure}
\vfill\break
Nella figura \ref{fig:architettura-collector} viene mostrato il funzionamento e il flusso dei dati all'interno del \textit{collector} e come esso si interfacci con le altre tecnologie utilizzate.
Nello specifico il \textit{collector} è composto da 3 parti principali:
\begin{itemize}
\item Un Python script principale che coordina il tutto
\item Selenium
\item WebRTC Internals Exporter
\end{itemize}
Selenium e WebRTC Internals Exporter li abbiamo già descritti in precedenza, mentre il Python script è il cuore del sistema, che si occupa di coordinare le altre componenti, di avviare e fermare i test, di raccogliere i dati, aggregarli e di inviarli a Telegraf per l'invio al database.
L'intero progetto è disponibile qui:
\begin{itemize}
\item \url{https://gitea.kobim.cloud/kobim/peertube-collector}
\end{itemize}
\subsection{Difficoltà incontrate e soluzioni}
Durante la creazione del sistema, abbiamo incontrato diverse difficoltà, per lo più sistemistiche, che hanno richiesto soluzioni creative per superarle. Alcune delle principali sfide sono state:
\begin{itemize}
\item \textbf{Accesso agli indirizzi IP forniti da WebRTC}: WebRTC dalle ultime versioni come misura di sicurezza e privacy, non permette più l'accesso e la visualizzazione degli indirizzi IP locali delle macchine coinvolte nella connessione grazie a tecniche di offuscazione, rendendo difficile la raccolta di queste informazioni. Per ovviare a questo problema ci siamo avvalsi di 2 soluzioni: la prima consiste nell'utilizzare una versione vecchia di Chromium, nello specifico una versone anteriore o uguale alla 129.0, in quanto in queste versioni l'offuscazione è presente ma è possibile disabilitarla tramite un flag da interfaccia grafica; la seconda soluzione invece consiste proprio nel disabilitarequesta funzionalità ma da riga di comando tramite un altro flag, all'avvio del browser.
\item \textbf{Limitazioni delle API di Peertube}: PeerTube fornisce delle API per la gestione della piattaforma, moderazione dei video, e altro ancora, ma non fornisce API per la raccolta delle metriche dei video. Alcune metriche generiche sono esposte via OpenTelemetry ma non sono specifiche per un singolo utente o video. Per ovviare a questo problema, abbiamo utilizzato il data scraping per estrarre le metriche direttamente dalla pagina web.
\item \textbf{Gestione delle variabili d'ambiente nell'estensione Chrome}: WebRTC Internals Exporter è un'estensione per Chromium che consente di esportare le metriche WebRTC da un browser in un formato leggibile e analizzabile. Tuttavia, l'estensione non supporta la sostituzione delle variabili d'ambiente nel codice JavaScript, in quanto viene caricata ed eseguita runtime in un ambiente isolato, rendendo difficile la configurazione dinamica dell'estensione. L'utilizzo di WebPack ci consente di configurare l'estensione in fase di complilazione, sostituendo le variabili d'ambiente con i valori corretti prima di caricarla nel browser.
\item \textbf{Raccolta dei dati dei test su macchine virtuali distribuite}: Data la distribuzione geografica delle nostre macchine virtuali di test, abbiamo dovuto affrontare la sfida di raccogliere ed aggregare i dati in modo efficiente e coordinato. Questa sfida l'abbiamo risolta utilizzando Telegraf come agente di raccolta dati su ogni VM, configurandolo per inviare le metriche ad un'istanza centrale di MongoDB. MongoDB è stato scelto per il suo supporto nativo a documenti JSON e per la capacità di gestire grandi volumi di dati time-series provenienti da fonti eterogenee.Le API di Hetzner Cloud ci hanno permesso di automatizzare il deployment e la configurazione di tutte queste componenti su macchine distribuite in diverse regioni geografiche.
\end{itemize}
\subsection{Python script}
Il funzionamento dello script è relativamente semplice; vengono eseguiti dei passaggi in successione per arrivare in una situazione in cui i dati sono costantemente raccolti e inviati al database creando quindi un ciclo infinito che si ripete ogni 2 secondi circa, fin quando il test non viene fermato.
\
Importante particolarità dello script è la possibilità di creare e caricare plugin personalizzati che permettono di estrarre metriche di vario tipo da potenzialmente qualsiasi pagina web e non solo da PeerTube. Questo potenzialmente permette di estendere il sistema di test a qualsiasi altra piattaforma di video streaming, o di qualsiasi altro tipo, semplicemente creando un plugin personalizzato.
Questa funzionalità è stata implementata utilizzando le \textit{Abstract Base Classes} di Python, che permettono di definire delle classi base che devono essere implementate dalle classi derivate, e che permettono di definire delle interfacce comuni.
\begin{lstlisting}[caption={Abstract Base Classes}, captionpos=b, basicstyle=\scriptsize]
# Abstract Base Classes for Plugins
class StatsSetupPlugin(abc.ABC):
@abc.abstractmethod
def setup_stats(
self,
driver: webdriver.Remote | webdriver.Chrome,
url: str,
retries: int = 5
) -> webdriver.Remote | webdriver.Chrome:
pass
class StatsDownloadPlugin(abc.ABC):
@abc.abstractmethod
def download_stats(
self,
driver: webdriver.Remote | webdriver.Chrome,
peersDict: dict,
socket_url: str,
socket_port: int
):
pass
@staticmethod
def saveStats(stats: list, socket_url: str, socket_port: int):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
logger.debug(f'Saving stats: {json.dumps(stats, indent=4)}')
sock.sendto(json.dumps(stats).encode(), (socket_url, socket_port))
sock.close()
logger.debug('Sent stats to socket.')
except socket.error as e:
logger.error(f'Got socket error: {e}')
\end{lstlisting}
Per tutto questo, alla creazione, abbiamo fatto uso di alcune librerie Python tra cui: \textit{selenium} e \textit{beautifulsoup4}.
\\ \textit{BeautifulSoup} è una libreria Python che permette di estrarre dati da file HTML e XML. È in grado di navigare nella struttura del documento, estrarre i dati, modificarli e salvare le modifiche. È spesso utilizzata per fare \textit{web scraping}. Assieme, quste due librerie, ci permettono di interagire con il browser e di estrarre i dati necessari dalla pagina web di PeerTube.\cite{10617017}
I passaggi presenti in figura \ref{fig:architettura-collector} possono essere riassunti come:
\begin{itemize}
\item \textbf{Inizializzazione}: Viene impostata da riga di comando o tramite variabili d'ambiente la configurazione del test.
\begin{description}
\item Queste possono includere: I plugin personalizzati BeautifulSoup, l'URL del video da analizzare, l'URL del server Telegraf, l'URL dell'hub di Selenium Grid, il percorso dell'estensione di WebRTC Internals Exporter, e altro ancora.
\end{description}
\item \textbf{Avvio del browser}: Viene avviato il browser ed aperta la pagina del video specificato tramite Selenium, con l'estensione di WebRTC Internals Exporter installata ed abilitata. Viene anche avviato in ascolto un server HTTP in background per ricevere le metriche WebRTC tramite un endpoint locale POST dedicato.
\item \textbf{Avvio del test}: Viene caricata la pagina del video e tramite Selenium viene controllato che il video sia in riproduzione tramite il controllo dell'esistenza del bottone play.
\item \textbf{Raccolta delle metriche WebRTC}: L'estensione per WebRTC inizia a raccogliere le metriche e ogni 2 secondi circa le invia allo script principale. Viene quindi di fatto instaurato un ciclo che viene usato dallo script come sorgente di clock per la raccolta delle altre metriche.
\item \textbf{Raccolta delle metriche video di PeerTube}: Utilizzando BeautifulSoup, vengono trasformate e raccolte le metriche del player video di PeerTube, come la qualità del video, il buffering, quantità di dati trasferiti, la latenza, e altro ancora. Il tutto viee convertito in un formato JSON.
\item \textbf{Invio delle metriche a Telegraf}: Le metriche raccolte, vengono inviate a Telegraf tramite una socket di sistema, per l'elaborazione e l'invio al database finale, nel nostro caso MongoDB. C'è un passaggio fondamentale però che Telegraf esegue, ed è quello di fare \textit{string-join} dei dati JSON, ovvero di `appiattire' e trasformare i dati in una stringa, per poi inviarli al database. Questo viene fatto in quanto Telegraf, utilizzando il plugin di input per il formato JSON, converte gli array \textbf{in singole metriche separate}, e non come un unico documento, perdendo quindi la struttura originale dei dati. In se qusto non è un problema, ma per la nostra analisi, è fondamentale mantenere la struttura originale dei dati per facilitarci il lavoro. Infine per ricavare i documenti interi, un ulteriore passaggio finale va effettuato nel database, in differita, per convertirli da stringhe ad oggetti JSON validi.
\end{itemize}
Va inoltre evidenziata la scelta di utilizzare un solo script Python per coordinare il tutto, sia l'inizializzazione che raccolta delle metriche dalle pagine web e dalla estensione esterna, in quanto questo ha semplificato la gestione e soprattutto la creazione del sistema e permette come bonus di avere un unico punto di controllo per l'intero processo.
\newpage
\begin{lstlisting}[caption={Codice del plugin per la raccolta delle metriche di PeerTube}, captionpos=b, basicstyle=\scriptsize]
# Default Plugin Implementation
class DefaultStatsSetupPlugin(StatsSetupPlugin):
def setup_stats(
self, driver: webdriver.Remote,
url: str,
retries: int = 5
) -> webdriver.Remote:
logger.log(logging.INFO, 'Setting up stats.')
actions = ActionChains(driver)
wait = WebDriverWait(driver, 30, poll_frequency=0.2)
sleep(2)
for attempt in range(retries):
driver.get(url)
try:
wait.until(
ec.presence_of_element_located(
(By.CLASS_NAME, 'vjs-big-play-button')
)
)
break
except Exception:
logger.error(
f'Timeout. Attempt {attempt + 1} of {retries}'
)
if attempt == retries - 1:
logger.error('Timeout limit reached. Exiting.')
driver.quit()
raise SystemExit(1)
actions.click(
driver.find_element(By.CLASS_NAME ,'video-js')
).perform()
wait.until(
ec.visibility_of_element_located((By.CLASS_NAME, 'vjs-control-bar'))
)
actions.context_click(
driver.find_element(By.CLASS_NAME ,'video-js')
.perform()
statsForNerds = driver.find_elements(
By.CLASS_NAME ,'vjs-menu-item'
actions.click(statsForNerds[-1]).perform()
wait.until(
ec.presence_of_element_located(
(By.CSS_SELECTOR, 'div.vjs-stats-content[style="display: block;"]')
)
)
actions.move_to_element(
driver.find_element(By.CLASS_NAME ,'vjs-control-bar')
).perform()
logger.log(logging.INFO, 'Stats setup complete.')
return driver
\end{lstlisting}
\newpage
Il diagramma finale dell'architettura del nostro sistema è il seguente:
\begin{itemize}
\item Un server centrale che esegue un'istanza di PeerTube e che raccoglie le metriche fornite da OpenTelemetry.
\item Molteplici macchine virtuali distribuite geograficamente sul globo che simulano gli spettatori.
\item Una applicazione Python in esecuzione su ogni singola macchina, che coordina Selenium e Telegraf per raccogliere le statistiche del video in riproduzione e le metriche WebRTC.
\item Un database centralizzato per la raccolta dei dati.
\end{itemize}
\section{Casi d'uso e scenari di test riprodotti}
Come descritto in precedenza, abbiamo riprodotto due scenari di test principali dei 4 casi d'uso descritti nell'articolo di PeerTube per motivi di tempo e risorse. Questi sono:
\begin{itemize}
\item Live streaming con impostazione \textit{Normal Latency}: Il setup standard di PeerTube
\item Live streaming con impostazione \textit{High Latency}: La configurazione che privilegia il P2P a scapito della latenza
\end{itemize}
Per ciascun scenario, abbiamo impostato il numero di spettatori/utenti a 5 (limite di Hetzner Cloud per account nuovi) e racolto le seguenti statistiche:
\begin{itemize}
\item Statistiche del player web (risoluzione, bitrate, buffering, latenza, ecc.)
\item Statistiche WebRTC (peer connection, ICE candidates, ICE connection state, ecc.)
\item Informazioni identificative dei singoli peer (url del video, ID sessione, ID peer)
\item Timestamp di raccolta
\end{itemize}
\chapter{Analisi dei dati e risultati}
[Questa sezione sarà completata la prossima settimana con i risultati dei test]
\chapter{Conclusioni}
[Questa sezione sarà completata dopo l'analisi dei dati]
\nocite{*}
\printbibliography
\addcontentsline{toc}{chapter}{Bibliografia}
\end{document}