44import queue
55import threading
66from collections import defaultdict
7+ from collections .abc import Generator
78from contextlib import contextmanager
8- from typing import Generator
99
1010from odoo .api import Environment
1111
@@ -45,8 +45,8 @@ class FastApiAppPool:
4545 updated by the increment of the `cache_sequence` SQL sequence. This cache sequence
4646 on the registry is reloaded from the DB on each request made to a specific database.
4747 When an app is retrieved from the pool, we always compare the cache sequence of
48- the pool with the cache sequence of the registry. If the two sequences are different,
49- we invalidate the pool and save the new cache sequence on the pool.
48+ the pool with the cache sequence of the registry. If the two sequences are
49+ different, we invalidate the pool and save the new cache sequence on the pool.
5050
5151 The cache is based on a defaultdict of defaultdict of queue.Queue. We are cautious
5252 that the use of defaultdict is not thread-safe for operations that modify the
@@ -61,10 +61,10 @@ class FastApiAppPool:
6161 """
6262
6363 def __init__ (self ):
64- self ._queue_by_db_by_root_path : dict [
65- str , dict [ str , queue .Queue [ FastAPI ]]
66- ] = defaultdict ( lambda : defaultdict ( queue . Queue ) )
67- self .__cache_sequence = 0
64+ self ._queue_by_db_by_root_path : dict [str , dict [ str , queue . Queue [ FastAPI ]]] = (
65+ defaultdict ( lambda : defaultdict ( queue .Queue ))
66+ )
67+ self .__cache_sequences = {}
6868 self ._lock = threading .Lock ()
6969
7070 def __get_pool (self , env : Environment , root_path : str ) -> queue .Queue [FastAPI ]:
@@ -102,25 +102,31 @@ def get_app(
102102 finally :
103103 self .__return_app (env , app , root_path )
104104
105- @ property
106- def cache_sequence ( self ) -> int :
107- return self .__cache_sequence
105+ def get_cache_sequence ( self , key : str ) -> int :
106+ with self . _lock :
107+ return self .__cache_sequences . get ( key , 0 )
108108
109- @cache_sequence .setter
110- def cache_sequence (self , value : int ) -> None :
111- if value != self .__cache_sequence :
112- with self ._lock :
113- self .__cache_sequence = value
109+ def set_cache_sequence (self , key : str , value : int ) -> None :
110+ with self ._lock :
111+ if (
112+ key not in self .__cache_sequences
113+ or value != self .__cache_sequences [key ]
114+ ):
115+ self .__cache_sequences [key ] = value
114116
115117 def _check_cache (self , env : Environment ) -> None :
116- cache_sequence = env .registry .cache_sequence
117- if cache_sequence != self .cache_sequence and self .cache_sequence != 0 :
118- _logger .info (
119- "Cache registry updated, reset fastapi_app pool for the current "
120- "database"
121- )
122- self .invalidate (env )
123- self .cache_sequence = cache_sequence
118+ cache_sequences = env .registry .cache_sequences
119+ for key , value in cache_sequences .items ():
120+ if (
121+ value != self .get_cache_sequence (key )
122+ and self .get_cache_sequence (key ) != 0
123+ ):
124+ _logger .info (
125+ "Cache registry updated, reset fastapi_app pool for the current "
126+ "database"
127+ )
128+ self .invalidate (env )
129+ self .set_cache_sequence (key , value )
124130
125131 def invalidate (self , env : Environment , root_path : str | None = None ) -> None :
126132 db_name = env .cr .dbname
0 commit comments