Member of The Internet Defense League Últimos cambios
Últimos Cambios
Blog personal: El hilo del laberinto Geocaching

Actualización de tráfico por tiempo, no por actividad

Última Actualización: 29 de noviembre de 2010 - Lunes

Con mis parches, el cliente BitTornado actualiza las estadísticas de tráfico de cada torrent en el sistema de persistencia cada vez que se manda o se recibe un fragmento, típicamente de 16KB.

Ahora que hospedo el servicio P2P en una máquina con una conexión de 100Mbps bidireccional con Internet, podríamos tener que actualizar los datos persistentes unas 1200 veces por segundo (600 por sentido). La carga que supone este tráfico de cambios sobre el sistema de persistencia se nota, y compite con la actividad de disco necesaria para mantener ese nivel tráfico.

El parche que publico a continuación acumula el tráfico y lo vuelca al sistema de persistencia una vez por segundo. Por tanto, con este parche el tráfico al sistema de persistencia es controlable y constante, independientemente del tráfico P2P que tengamos.

El único problema es que si el cliente BT muere de alguna forma (cuelgue de máquina, fallo del programa, ...), podemos perder la estadística del último segundo de tráfico. Si tenemos un tráfico P2P muy elevado, esa falta de precisión puede ser numéricamente significativa, pero lo cierto es que sería simplemente un segundo de actividad. Aunque fueran muchos megas, comparativamente con el minuto anterior, que sí hemos contabilizado, el valor percentual es despreciable.

El parche:

diff -r a32f9b12b76c -r 450266697e73 BitTornado/CurrentRateMeasure.py
--- a/BitTornado/CurrentRateMeasure.py  Fri Feb 05 14:07:15 2010 +0100
+++ b/BitTornado/CurrentRateMeasure.py  Fri Feb 26 05:08:55 2010 +0100
@@ -7,6 +7,9 @@
 
 from time import time
 
+trafico={}
+trafico_timeout=0
+
 class MeasureDurus:
     def __init__(self, max_rate_period, infohash,up,fudge = 1):
         self.max_rate_period = max_rate_period
@@ -27,19 +30,31 @@
         self.total=x(self.infohash,self.up)
 
     def update_rate(self, amount):
+        global trafico_timeout
         @monitor_opt
-        def x(conn,infohash,up,amount) :
+        def x(conn,infohash) :
+          global trafico_timeout
+          flush_trafico=False
           speed=conn.get_root()["BT"]["trafico"]
+          t=time()
+          if trafico_timeout<t :
+            for i,j in trafico.iteritems() :
+              x=speed[i]
+              speed[i]=[x[0]+j[0], x[1]+j[1], t]
+            flush_trafico=True
+            trafico_timeout=0
+
           x=speed[infohash]
-          total=x[up]+amount
-          if amount :  # Solo graba si hay algo que grabar
-            x[up]=total
-            x[2]=time()
-            speed[infohash]=x
-            return (True,total)
-          return (False,total)
-          
-        self.total=x(self.infohash,self.up,amount)
+          return (flush_trafico,x)
+
+        traf=trafico.get(self.infohash,[0,0])
+        if amount :
+          traf[self.up]+=amount
+          trafico[self.infohash]=traf
+        self.total=x(self.infohash)[self.up]+traf[self.up]
+        if not trafico_timeout :  # Hemos hecho flush
+          trafico.clear()
+          trafico_timeout=time()+1
 
         t = clock()
         self.rate = (self.rate * (self.last - self.ratesince) +


Historia

  • 29/nov/10: Primera versión de esta página.



Python Zope ©2010 jcea@jcea.es

Más información sobre los OpenBadges

Donación BitCoin: 19niBN42ac2pqDQFx6GJZxry2JQSFvwAfS