You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CoAP/coapthon/client/superviseur.py

159 lines
4.5 KiB
Python

import random
import time
import numpy as np
from coapthon import defines
class SuperviseurLocalPlaceHolder():
"""Class de base pour le superviseur
"""
def __init__(self, client_CoAP) -> None:
client_CoAP.superviseur = self
self.client = client_CoAP
self._RTTs = []
self._taux_retransmition = 0
self._RTO = defines.ACK_TIMEOUT
def envoie_message(self, message) -> None:
self.envoie_token(message.token)
def reception_message(self, message) -> None:
self.reception_token(message.token)
def envoie_token(self, token) -> None:
pass
def reception_token(self, tokken) -> None:
pass
@property
def RTTs(self):
return self._RTTs
@property
def taux_retransmission(self):
return self._taux_retransmition
@property
def min_RTT(self):
"""Valeur minimum du RTT"""
return min(self.RTTs)
@property
def avg_RTT(self):
"""Moyenne du RTT."""
return sum(self.RTTs)/len(self.RTTs)
@property
def RTO(self):
return random.uniform(self._RTO, (self._RTO * defines.ACK_RANDOM_FACTOR))
class SuperviseurLocal(SuperviseurLocalPlaceHolder):
"""
Class implementant la supervision local de chaque client.
"""
def __init__(self, client_CoAP) -> None:
super().__init__(client_CoAP)
self._dict_envoie = {}
self._n_envoie = 0
self._n_tokken = 0
def envoie_token(self, token) -> None:
"""Enregistre l'envoie d'un token
Args:
token (int): Token à enregistrer
"""
self._n_envoie += 1
self._n_tokken += not(token in self._dict_envoie)
self._dict_envoie[token] = time.time()
self._taux_retransmition = 1 - self._n_tokken/self._n_envoie
def reception_token(self, token) -> None:
"""Enregistre l'arrivée d'un token
Args:
token (int): Token à enregister
"""
if token in self._dict_envoie:
rtt = time.time() - self._dict_envoie[token]
self._RTTs.append(time.time() - self._dict_envoie[token])
# del self._dict_envoie[token]
self.callback_new_rtt(rtt)
else:
pass # raise ValueError("Tokken inconnue")
def callback_new_rtt(self, rtt):
pass
def reset(self):
self._dict_envoie = {}
self._n_envoie = 0
self._n_tokken = 0
self._RTTs = []
class SuperviseurLocalFiltre(SuperviseurLocal):
def __init__(self, client_CoAP, rtt_init=0.01, alpha_l=0.01, alpha_s=0.1) -> None:
super().__init__(client_CoAP)
self.alpha_l = alpha_l
self.alpha_s = alpha_s
self._RTT_L = rtt_init
self._RTT_S = rtt_init
def callback_new_rtt(self, rtt):
self._RTT_L = rtt*self.alpha_l + (1 - self.alpha_l) * self._RTT_L
self._RTT_S = rtt*self.alpha_s + (1 - self.alpha_s) * self._RTT_S
return super().callback_new_rtt(rtt)
@property
def RTT_L(self):
return self._RTT_L
@property
def RTT_S(self):
return self._RTT_S
class SuperviseurGlobal():
def __init__(self, clients, superviseur_type, *superviseur_args) -> None:
"""Genère un superviseur global pour la liste de client donnée
Args:
clients (List(HelperClient)): Liste des clients à supervisé
superviseur_type (Type): Type de superviseur à utilisé
"""
self.clients = clients
self.superviseurs = [superviseur_type(
client, *superviseur_args) for client in clients]
@property
def state(self):
taux_retransmissions = np.array(
[superviseur.taux_retransmission for superviseur in self.superviseurs])
min_rtts = np.array(
[superviseur.min_RTT for superviseur in self.superviseurs])
avg_rtts = np.array(
[superviseur.avg_RTT for superviseur in self.superviseurs])
ratio_rtts = np.array(min_rtts/avg_rtts)
if isinstance(self.superviseurs[0], SuperviseurLocalFiltre):
rtt_ls = np.array(
[superviseur.RTT_L for superviseur in self.superviseurs])
rtt_ss = np.array(
[superviseur.RTT_S for superviseur in self.superviseurs])
ratio_filtres = rtt_ss/rtt_ls
representation_etat = np.array(
[taux_retransmissions, ratio_rtts, ratio_filtres])
else:
representation_etat = np.array([taux_retransmissions, ratio_rtts])
return representation_etat