2 hours later…
10:46 AM
import asyncio import math import time import sys class TimeoutManager: def __init__( self, sleepRound = 1.0, sleepTime = 1.0 ): self._sleepRound = sleepRound self._sleepTime = sleepTime self._list = [ ] self._index = { } self._nextIdValue = 0 self._stop = False self._stopEvent = None self._queued = 0 self._timed = 0 self._poped = 0 def __sizeof__( self ): return len( self._list ) @property def queued( self ):
Manager creado Timeout en id 5 data5 Timeout en id 4 data4 Timeout en id 3 data3 Timeout en id 2 data2
2 hours later…
12:27 PM
@Trauma Buff.. me está costando entenderlo. ¿Por qué generas un range "hacia atrás"? ¿Supones que _list está ordenado por timeout? Y aún en ese caso ¿no debería ir hacia adelante? Habrá que comprobar antes los timeouts más cercanos en el tiempo, digo yo, pues la tarea 1 terminará antes que la 5
pero claro, ya que tienes
if self._list[listIdx][0] > now: break
, y empiezas por el final (y la tarea final es la que tiene el timeout más tardío) esa condición se va a cumplir siempre hasta que hayan transcurrido los 5 segundos. Así que debido al break el resto de tareas no se examinan
si dejo de lado lo de
self._index
, puedo reescribir tu bucle de gestión de timeouts de una forma mucho más pythónica y legible para mi. Así:
async def _onTimeoutCode( self ): while self._stop == False: await asyncio.sleep( self._sleepTime ) limit = None now = time.time( ) print(self._list) for listIdx, (timeout, id, data, callback) in enumerate(self._list): if timeout > now: continue if callback is not None: self._timed += 1 await callback(id, data) limit = listIdx # del self._index[listIdx]
Recorro la lista hacia adelante en vez de hacia atrás. Uso continue en vez de break para saltarme a los que no han excedido el timeout (no presupongo orden en la lista). Llamo al callback de los que han excedido el timeout, y luego los borro de la lista
async def _onTimeoutCode( self ): while self._stop == False: await asyncio.sleep( self._sleepTime ) limit = None now = time.time( ) a_borrar = [] for listIdx, (timeout, id, data, callback) in enumerate(self._list): if timeout > now: continue if callback is not None: self._timed += 1 await callback(id, data) a_borrar.append(listIdx) # del self._index[listIdx]
quité eso de
limit
que tampoco entendía. ¿Por qué borrabas todo de limit en adelante? De nuevo parece que presupones una ordenación por timeouts en la lista
@trauma Y otro detalle, esto ya de asincronía... ¿realmente quieres hacer un await delante del callback? Eso los serializa... hasta que un callback no termine no podrías iniciar otro. Creo que lo suyo sería lanzarlos todos como tareas sin esperar por ellos, aunque eso ya no sé cómo se hace con asyncio
@trauma Ah, creo que ya entiendo de qué va lo de
self._index
pero tienes varias cosas mal. Si no me equivoco cuando lo inicializas debería ser self._index[id] = index
, pero tú tienes self._index[index]=id
Con ese cambio y la siguiente modificación (espero que final) a
_onTimeoutCode()
, creo que ya funciona
import asyncio import math import time import sys class TimeoutManager: def __init__( self, sleepRound = 1.0, sleepTime = 1.0 ): self._sleepRound = sleepRound self._sleepTime = sleepTime self._list = [ ] self._index = { } self._nextIdValue = 0 self._stop = False self._stopEvent = None self._queued = 0 self._timed = 0 self._poped = 0 def __sizeof__( self ): return len( self._list ) @property def queued( self ):
48c48 < self._index[index] = id --- > self._index[id] = index 68d67 < 71,76c70,73 < for listIdx in range( len( self._list ) - 1, 0, -1 ): < if self._list[listIdx][0] > now: break < < realData = self._list[listIdx] < < if realData[3] is not None: --- > a_borrar = [] > for listIdx, (timeout, id, data, callback) in enumerate(self._list): > if timeout > now: continue > if callback is not None:
1:07 PM
Gracias @abulafia. Tienes razón en lo que dices. Se ve que está mañana estaba yo especialmente ... espeso O_º
Lo he resuelto por mi lado, sacando el código a una función suelta. El tuyo me gusta mas, el mio sigue siendo poco pythonico xD
1:33 PM
@Trauma me suena que python tiene listas ordenadas basadas en arboles rojo-negro (no sé bien qué estoy diciendo), que permite insertar elementos en O(log N) o algo asi, manteniéndolos ordenados. Probablemente habría que usar algo de esto para tenerlos ordenados por timeout, asi no necesitas recorrer la lista entera cada vez
2 hours later…
2 hours later…
4:57 PM
5:20 PM
aunque como entrada en algun lado seria muy interesante... pero mas que para un lenguaje, algo canonico de estrategias de depuracion...
2 hours later…
2 hours later…
« first day (2472 days earlier) ← previous day next day → last day (640 days later) »