55configured. CpuInstanceType values are backend cpu flavor ids.
66"""
77
8- import functools
98import logging
109import os
10+ import time
1111from enum import Enum
12- from typing import Dict , List , Optional , Set , Union
12+ from typing import Any , Dict , List , Optional , Set , Union
1313
1414log = logging .getLogger (__name__ )
1515
@@ -216,18 +216,29 @@ def resolve_gpu_string(value: str) -> List[str]:
216216CATALOG_URL = "https://api.runpod.io/v2/catalog/gpus"
217217
218218
219- @functools .lru_cache (maxsize = 1 )
219+ # live catalog result, or when it last failed
220+ _catalog : Dict [str , Any ] = {}
221+ _CATALOG_RETRY_SECONDS = 60.0
222+
223+
220224def live_pool_members () -> Optional [Dict [str , Set [str ]]]:
221225 """pool id -> device ids, from the platform's gpu catalog.
222226
223227 the static POOLS_TO_TYPES table lags the platform (pools gain mig
224228 slices and new skus), so exact-device pinning reads the live
225- membership. returns None when the catalog is unreachable.
229+ membership. returns None when the catalog is unreachable. a result
230+ is kept for the process; a failure is retried after a minute.
226231 """
227232 import requests
228233
229234 from .utils .network import api_key
230235
236+ if _catalog .get ("members" ) is not None :
237+ return _catalog ["members" ]
238+ failed_at = _catalog .get ("failed_at" )
239+ if failed_at is not None and time .monotonic () - failed_at < _CATALOG_RETRY_SECONDS :
240+ return None
241+
231242 url = os .environ .get ("RUNPOD_GPU_CATALOG_URL" , CATALOG_URL )
232243 try :
233244 resp = requests .get (
@@ -240,12 +251,23 @@ def live_pool_members() -> Optional[Dict[str, Set[str]]]:
240251 for gpu in gpus :
241252 if gpu .get ("pool" ) and gpu .get ("id" ):
242253 members .setdefault (gpu ["pool" ], set ()).add (gpu ["id" ])
243- return members or None
254+ if not members :
255+ raise ValueError ("catalog lists no pools" )
256+ _catalog ["members" ] = members
257+ return members
244258 except Exception as exc : # any failure falls back to the static table
245- log .debug ("gpu catalog unavailable (%s); using the static pool table" , exc )
259+ _catalog ["failed_at" ] = time .monotonic ()
260+ log .warning (
261+ "gpu catalog unavailable (%s); device pins use the static pool "
262+ "table, which can miss newer devices in a pool" ,
263+ exc ,
264+ )
246265 return None
247266
248267
268+ live_pool_members .cache_clear = _catalog .clear # type: ignore[attr-defined]
269+
270+
249271def _pool_members (pool : str ) -> Set [str ]:
250272 live = live_pool_members ()
251273 if live is not None and pool in live :
0 commit comments