mirror of
https://github.com/varun-r-mallya/py-libp2p.git
synced 2025-12-31 20:36:24 +00:00
added dedicated test file and moved timed_cache to tools
This commit is contained in:
@ -424,7 +424,6 @@ class GossipsubFactory(factory.Factory):
|
||||
degree = GOSSIPSUB_PARAMS.degree
|
||||
degree_low = GOSSIPSUB_PARAMS.degree_low
|
||||
degree_high = GOSSIPSUB_PARAMS.degree_high
|
||||
time_to_live = GOSSIPSUB_PARAMS.time_to_live
|
||||
gossip_window = GOSSIPSUB_PARAMS.gossip_window
|
||||
gossip_history = GOSSIPSUB_PARAMS.gossip_history
|
||||
heartbeat_initial_delay = GOSSIPSUB_PARAMS.heartbeat_initial_delay
|
||||
@ -448,6 +447,7 @@ class PubsubFactory(factory.Factory):
|
||||
router: IPubsubRouter,
|
||||
cache_size: int,
|
||||
seen_ttl: int,
|
||||
sweep_interval: int,
|
||||
strict_signing: bool,
|
||||
msg_id_constructor: Callable[[rpc_pb2.Message], bytes] = None,
|
||||
) -> AsyncIterator[Pubsub]:
|
||||
@ -456,6 +456,7 @@ class PubsubFactory(factory.Factory):
|
||||
router=router,
|
||||
cache_size=cache_size,
|
||||
seen_ttl=seen_ttl,
|
||||
sweep_interval=sweep_interval,
|
||||
strict_signing=strict_signing,
|
||||
msg_id_constructor=msg_id_constructor,
|
||||
)
|
||||
@ -470,7 +471,8 @@ class PubsubFactory(factory.Factory):
|
||||
number: int,
|
||||
routers: Sequence[IPubsubRouter],
|
||||
cache_size: int = None,
|
||||
seen_ttl: int = None,
|
||||
seen_ttl: int = 120,
|
||||
sweep_interval: int = 60,
|
||||
strict_signing: bool = False,
|
||||
security_protocol: TProtocol = None,
|
||||
muxer_opt: TMuxerOptions = None,
|
||||
@ -488,6 +490,7 @@ class PubsubFactory(factory.Factory):
|
||||
router,
|
||||
cache_size,
|
||||
seen_ttl,
|
||||
sweep_interval,
|
||||
strict_signing,
|
||||
msg_id_constructor,
|
||||
)
|
||||
@ -503,6 +506,7 @@ class PubsubFactory(factory.Factory):
|
||||
number: int,
|
||||
cache_size: int = None,
|
||||
seen_ttl: int = 120,
|
||||
sweep_interval: int = 60,
|
||||
strict_signing: bool = False,
|
||||
protocols: Sequence[TProtocol] = None,
|
||||
security_protocol: TProtocol = None,
|
||||
@ -520,6 +524,7 @@ class PubsubFactory(factory.Factory):
|
||||
floodsubs,
|
||||
cache_size,
|
||||
seen_ttl,
|
||||
sweep_interval,
|
||||
strict_signing,
|
||||
security_protocol=security_protocol,
|
||||
muxer_opt=muxer_opt,
|
||||
@ -567,7 +572,6 @@ class PubsubFactory(factory.Factory):
|
||||
degree=degree,
|
||||
degree_low=degree_low,
|
||||
degree_high=degree_high,
|
||||
time_to_live=time_to_live,
|
||||
gossip_window=gossip_window,
|
||||
heartbeat_interval=heartbeat_interval,
|
||||
)
|
||||
|
||||
0
libp2p/tools/timed_cache/__init__.py
Normal file
0
libp2p/tools/timed_cache/__init__.py
Normal file
54
libp2p/tools/timed_cache/base_timed_cache.py
Normal file
54
libp2p/tools/timed_cache/base_timed_cache.py
Normal file
@ -0,0 +1,54 @@
|
||||
from abc import (
|
||||
ABC,
|
||||
abstractmethod,
|
||||
)
|
||||
import threading
|
||||
import time
|
||||
|
||||
|
||||
class BaseTimedCache(ABC):
|
||||
"""Base class for Timed Cache with cleanup mechanism."""
|
||||
|
||||
cache: dict[bytes, int]
|
||||
|
||||
def __init__(self, ttl: int, sweep_interval: int = 60) -> None:
|
||||
"""
|
||||
Initialize a new BaseTimedCache with a time-to-live for cache entries
|
||||
|
||||
:param ttl: no of seconds as time-to-live for each cache entry
|
||||
"""
|
||||
self.ttl = ttl
|
||||
self.sweep_interval = sweep_interval
|
||||
self.lock = threading.Lock()
|
||||
self.cache = {}
|
||||
self._stop_event = threading.Event()
|
||||
self._thread = threading.Thread(target=self._background_cleanup, daemon=True)
|
||||
self._thread.start()
|
||||
|
||||
def _background_cleanup(self) -> None:
|
||||
while not self._stop_event.wait(self.sweep_interval):
|
||||
self._sweep()
|
||||
|
||||
def _sweep(self) -> None:
|
||||
"""Removes expired entries from the cache."""
|
||||
now = time.time()
|
||||
with self.lock:
|
||||
keys_to_remove = [key for key, expiry in self.cache.items() if expiry < now]
|
||||
for key in keys_to_remove:
|
||||
del self.cache[key]
|
||||
|
||||
def stop(self) -> None:
|
||||
"""Stops the background cleanup thread."""
|
||||
self._stop_event.set()
|
||||
self._thread.join()
|
||||
|
||||
def length(self) -> int:
|
||||
return len(self.cache)
|
||||
|
||||
@abstractmethod
|
||||
def add(self, key: bytes) -> bool:
|
||||
"""To be implemented in subclasses."""
|
||||
|
||||
@abstractmethod
|
||||
def has(self, key: bytes) -> bool:
|
||||
"""To be implemented in subclasses."""
|
||||
20
libp2p/tools/timed_cache/first_seen_cache.py
Normal file
20
libp2p/tools/timed_cache/first_seen_cache.py
Normal file
@ -0,0 +1,20 @@
|
||||
import time
|
||||
|
||||
from .base_timed_cache import (
|
||||
BaseTimedCache,
|
||||
)
|
||||
|
||||
|
||||
class FirstSeenCache(BaseTimedCache):
|
||||
"""Cache where expiry is set only when first added."""
|
||||
|
||||
def add(self, key: bytes) -> bool:
|
||||
with self.lock:
|
||||
if key in self.cache:
|
||||
return False
|
||||
self.cache[key] = int(time.time()) + self.ttl
|
||||
return True
|
||||
|
||||
def has(self, key: bytes) -> bool:
|
||||
with self.lock:
|
||||
return key in self.cache
|
||||
22
libp2p/tools/timed_cache/last_seen_cache.py
Normal file
22
libp2p/tools/timed_cache/last_seen_cache.py
Normal file
@ -0,0 +1,22 @@
|
||||
import time
|
||||
|
||||
from .base_timed_cache import (
|
||||
BaseTimedCache,
|
||||
)
|
||||
|
||||
|
||||
class LastSeenCache(BaseTimedCache):
|
||||
"""Cache where expiry is updated on every access."""
|
||||
|
||||
def add(self, key: bytes) -> bool:
|
||||
with self.lock:
|
||||
is_new = key not in self.cache
|
||||
self.cache[key] = int(time.time()) + self.ttl
|
||||
return is_new
|
||||
|
||||
def has(self, key: bytes) -> bool:
|
||||
with self.lock:
|
||||
if key in self.cache:
|
||||
self.cache[key] = int(time.time()) + self.ttl
|
||||
return True
|
||||
return False
|
||||
Reference in New Issue
Block a user