11import dataclasses
22from time import monotonic
3- from typing import Dict
4- from typing import Tuple
3+ from typing import Set
54
65
76@dataclasses .dataclass (frozen = True )
@@ -10,11 +9,17 @@ class HttpEndPoint:
109 path : str
1110 resource_name : str = dataclasses .field (default = "" )
1211 operation_name : str = dataclasses .field (default = "http.request" )
12+ _hash : int = dataclasses .field (init = False , repr = False )
1313
1414 def __post_init__ (self ) -> None :
1515 super ().__setattr__ ("method" , self .method .upper ())
1616 if not self .resource_name :
1717 super ().__setattr__ ("resource_name" , f"{ self .method } { self .path } " )
18+ # cache hash result
19+ super ().__setattr__ ("_hash" , hash ((self .method , self .path )))
20+
21+ def __hash__ (self ) -> int :
22+ return self ._hash
1823
1924
2025@dataclasses .dataclass ()
@@ -25,7 +30,7 @@ class HttpEndPointsCollection:
2530 It maintains a maximum size and drops endpoints after a certain time period in case of a hot reload of the server.
2631 """
2732
28- endpoints : Dict [ Tuple [ str , str ], HttpEndPoint ] = dataclasses .field (default_factory = dict , init = False )
33+ endpoints : Set [ HttpEndPoint ] = dataclasses .field (default_factory = set , init = False )
2934 is_first : bool = dataclasses .field (default = True , init = False )
3035 drop_time_seconds : float = dataclasses .field (default = 90.0 , init = False )
3136 last_modification_time : float = dataclasses .field (default_factory = monotonic , init = False )
@@ -46,13 +51,13 @@ def add_endpoint(
4651 current_time = monotonic ()
4752 if current_time - self .last_modification_time > self .drop_time_seconds :
4853 self .reset ()
49- self .endpoints [( method , path )] = HttpEndPoint (
50- method = method , path = path , resource_name = resource_name , operation_name = operation_name
54+ self .endpoints . add (
55+ HttpEndPoint ( method = method , path = path , resource_name = resource_name , operation_name = operation_name )
5156 )
5257 elif len (self .endpoints ) < self .max_size_length :
5358 self .last_modification_time = current_time
54- self .endpoints [( method , path )] = HttpEndPoint (
55- method = method , path = path , resource_name = resource_name , operation_name = operation_name
59+ self .endpoints . add (
60+ HttpEndPoint ( method = method , path = path , resource_name = resource_name , operation_name = operation_name )
5661 )
5762
5863 def flush (self , max_length : int ) -> dict :
@@ -62,12 +67,12 @@ def flush(self, max_length: int) -> dict:
6267 if max_length >= len (self .endpoints ):
6368 res = {
6469 "is_first" : self .is_first ,
65- "endpoints" : [ dataclasses .asdict ( ep ) for ep in self .endpoints . values ()] ,
70+ "endpoints" : list ( map ( dataclasses .asdict , self .endpoints )) ,
6671 }
6772 self .reset ()
6873 return res
6974 else :
70- batch = [self .endpoints .popitem ()[ 1 ] for _ in range (max_length )]
75+ batch = [self .endpoints .pop () for _ in range (max_length )]
7176 res = {
7277 "is_first" : self .is_first ,
7378 "endpoints" : [dataclasses .asdict (ep ) for ep in batch ],
0 commit comments