@@ -50,6 +50,7 @@ class AdapterStore:
50
50
cache_path : str # Path to local store of adapters to load from
51
51
adapters : dict [str , AdapterMetadata ]
52
52
next_unique_id : int = 1
53
+ load_locks : dict [str , asyncio .Lock ] = dataclasses .field (default_factory = dict )
53
54
54
55
55
56
async def validate_adapters (
@@ -78,31 +79,35 @@ async def validate_adapters(
78
79
if not adapter_id or not adapter_store :
79
80
return {}
80
81
81
- # If not already cached, we need to validate that files exist and
82
- # grab the type out of the adapter_config.json file
83
- if (adapter_metadata := adapter_store .adapters .get (adapter_id )) is None :
84
- _reject_bad_adapter_id (adapter_id )
85
- local_adapter_path = str (Path (adapter_store .cache_path ) / adapter_id )
86
-
87
- loop = asyncio .get_running_loop ()
88
- if global_thread_pool is None :
89
- global_thread_pool = concurrent .futures .ThreadPoolExecutor (max_workers = 2 )
90
-
91
- # Increment the unique adapter id counter here in async land where we don't
92
- # need to deal with thread-safety
93
- unique_id = adapter_store .next_unique_id
94
- adapter_store .next_unique_id += 1
95
-
96
- adapter_metadata = await loop .run_in_executor (
97
- global_thread_pool ,
98
- _load_adapter_metadata ,
99
- adapter_id ,
100
- local_adapter_path ,
101
- unique_id ,
102
- )
103
-
104
- # Add to cache
105
- adapter_store .adapters [adapter_id ] = adapter_metadata
82
+ # Guard against concurrent access for the same adapter
83
+ async with adapter_store .load_locks .setdefault (adapter_id , asyncio .Lock ()):
84
+ # If not already cached, we need to validate that files exist and
85
+ # grab the type out of the adapter_config.json file
86
+ if (adapter_metadata := adapter_store .adapters .get (adapter_id )) is None :
87
+ _reject_bad_adapter_id (adapter_id )
88
+ local_adapter_path = str (Path (adapter_store .cache_path ) / adapter_id )
89
+
90
+ loop = asyncio .get_running_loop ()
91
+ if global_thread_pool is None :
92
+ global_thread_pool = concurrent .futures .ThreadPoolExecutor (
93
+ max_workers = 2
94
+ )
95
+
96
+ # Increment the unique adapter id counter here in async land where we don't
97
+ # need to deal with thread-safety
98
+ unique_id = adapter_store .next_unique_id
99
+ adapter_store .next_unique_id += 1
100
+
101
+ adapter_metadata = await loop .run_in_executor (
102
+ global_thread_pool ,
103
+ _load_adapter_metadata ,
104
+ adapter_id ,
105
+ local_adapter_path ,
106
+ unique_id ,
107
+ )
108
+
109
+ # Add to cache
110
+ adapter_store .adapters [adapter_id ] = adapter_metadata
106
111
107
112
# Build the proper vllm request object
108
113
if adapter_metadata .adapter_type == "LORA" :
0 commit comments