Cintes transportadores¶
En un centre de distribució automatitzat, disposem de desenes de cintes transportadores que informen del seu estat de funcionament (velocitat i alertes) a un servidor mitjançant connexions TCP asíncrones.
Servidor bàsic¶
Per tal d’implementar un servidor bàsic que gestioni les connexions d’un conjunt de cintes, fes el següent:
Dissenya la corutina següent i desa-la al mòdul
cintes(fitxercintes.py):- async cintes.gestiona_cinta(reader: asyncio.StreamReader, writer: asyncio.StreamWriter) None¶
Llegeix línia a línia de reader i respon
OKper writer. Enregistra les excepcions mitjançant el mòdullogging. Fa un tancament net de writer quan s’acaben les dades de reader o s’ha produït una excepció.
Passa-hi els tests del fitxer
test_gestiona_cinta.pyambpytest.
Dissenya un servidor basat en fluxos de dades (streams) d'
asyncioque usi la corutinagestiona_cinta()per atendre cada una de les connexions. Desa’l al mòdulservidor_basic.El servidor ha d’escoltar el port 7777 de l’ordinador local.
El servidor ha d’acabar de manera neta en rebre el senyal
SIGTERM.
Prova’l amb telnet o nc. Ha de respondre OK a cada línia enviada. Per exemple, havent engegat el servidor:
$ nc -N 127.0.0.1 7777 Hola OK Bon dia! OK Qualsevol cosa OK
Solució
Servidor amb l’estat de les cintes¶
El servidor ha d’emmagatzemar l’estat de cada cinta en un
diccionari. Les claus del diccionari són els identificadors de les
cintes. L’estat pot ser "ATURADA", "MOVIMENT" o
"AVARIADA". El servidor ha de calcular l’estat de cada cinta a
partir dels missatges rep de les cintes.
El protocol de missatges entre una cinta i el servidor és el següent:
El primer missatge que ha d’enviar una cinta al servidor és
ID identificador_de_la_cintaen quèidentificador_de_la_cintaés un text sense espais en blanc. El servidor responOK identificador_de_la_cinta.La resta de missatges de la cinta poden ser:
VELOCITAT ven quèvés un nombre més gran o igual que zero. El servidor ha de respondreOK ATURADAsivés igual a zero iOK MOVIMENTsivés més gran que zero.AVARIA. El servidor responOK ATURADA.
Recorda que cada missatge ha d’anar en una línia.
Cal que facis el següent:
Dissenya la corutina següent i desa-la al mòdul
cintes(fitxercintes.py):- async servidor_basic.gestiona_estat_cinta(estat, reader: asyncio.StreamReader, writer: asyncio.StreamWriter) None¶
Llegeix línia a línia de reader i respon per writer d’acord amb el protocol anterior. Emmagatzema l’estat de la cinta al diccionari estat. Enregistra les exepcions mitjançant el mòdul
logging. Fa un tancament net de writer quan s’acaben les dades de reader o s’ha produït una excepció.
Passa-hi els tests del fitxer
test_gestiona_estat_cinta.pyambpytest.
Dissenya un servidor basat en fluxos de dades (streams) d'
asyncioque usi la corutinagestiona_estat_cinta()per atendre cada una de les connexions i que mantingui l’estat de cada cinta en un diccionari compartit per totes les connexions. Desa’l al mòdulservidor_estat.El servidor ha d’escoltar el port 7777 de l’ordinador local.
El servidor ha d’acabar de manera neta en rebre el senyal
SIGTERM.
Prova’l amb telnet o nc. Recorda que has de seguir el protocol de la cinta. Per exemple, havent engegat el servidor:
$ nc -N 127.0.0.1 7777 ID cinta_1 OK cinta_1 VELOCITAT 100 OK MOVIMENT VELOCITAT 0 OK ATURADA AVARIA OK AVARIADA
Solució
Classe servidor¶
Ara volem reestructurar el codi anterior en una classe que implementi el Servidor amb l’estat de les cintes. Per això cal que facis el següent:
Dissenya la classe següent i desa-la al mòdul
servidor_classe:- class servidor_classe.ServidorEstatCintes¶
Implementa un servidor amb la mateixa funcionalitat que Servidor amb l’estat de les cintes.
Atributs
- estat_cintes¶
Diccionari amb l’estat de cada cinta connectada al servidor.
Mètodes
- async cinta(reader: asyncio.StreamReader, writer: asyncio.StreamWriter)¶
Equivalent a
gestiona_estat_cinta(), llevat que el diccionari és un atribut de l’objecte en comptes de ser un paràmetre.
- async run(ip, port)¶
Engega el servidor que escolta del port de l’adreça ip.
Dissenya el programa que usi aquesta classe i desa’l al mòdul
servidor_classe.Prova’l amb telnet o nc. S’ha de comportar com
servidor_estat.
Solució
Prova de càrrega¶
Volem mesurar el nombre de peticions per segon que poden atendre els
servidors anteriors. La prova de càrrega s’ha de comportar com
wrk:
Parteix del nombre màxim de connexions i de la durada de la prova de càrrega en segons.
Ha de calcular:
El nombre total de peticions fetes al servidor.
El nombre d’errors produïts.
El temps total d’execució.
El rendiment del servidor en nombre de peticions ateses per segon.
Cal que facis el següent:
Dissenya una prova de càrrega per als servidors anteriors que es comporti com
wrki desa-la al mòdulcintes_wrk. Per exemple:$ python3 cintes_wrk.py 10 5 Iniciant prova de 5 segons amb 10 connexions concurrents... Protocol: TCP Stream sobre 127.0.0.1:7777 --------------------------------------------- Peticions totals: 115721 Errors totals: 0 Temps real: 5.00 segons Rendiment (RPS): 23140.56 peticions/segon ---------------------------------------------
Solució