fix(options): cache instruments and backoff on OKX 50011
期权链拉取遇限频时退避重试并回退短缓存,前端提示更友好。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
"""期权合约列表缓存与限频退避."""
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
import unittest
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from lib.exchange import okx_options_lib as m
|
||||
|
||||
|
||||
class FetchOptionInstrumentsCacheTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
m.invalidate_option_instruments_cache()
|
||||
|
||||
def tearDown(self):
|
||||
m.invalidate_option_instruments_cache()
|
||||
|
||||
def test_cache_hit_skips_second_api_call(self):
|
||||
ex = MagicMock()
|
||||
ex.public_get_public_instruments.return_value = {
|
||||
"data": [
|
||||
{
|
||||
"instId": "ETH-USD_UM-260812-2000-C",
|
||||
"state": "live",
|
||||
"expTime": "9999999999999",
|
||||
}
|
||||
]
|
||||
}
|
||||
a = m.fetch_option_instruments(ex, "ETH-USD_UM")
|
||||
b = m.fetch_option_instruments(ex, "ETH-USD_UM")
|
||||
self.assertEqual(len(a), 1)
|
||||
self.assertEqual(len(b), 1)
|
||||
self.assertEqual(ex.public_get_public_instruments.call_count, 1)
|
||||
|
||||
@patch("lib.exchange.okx_options_lib.time.sleep", return_value=None)
|
||||
def test_rate_limit_falls_back_to_stale_cache(self, _sleep):
|
||||
ex = MagicMock()
|
||||
ex.public_get_public_instruments.return_value = {
|
||||
"data": [{"instId": "ETH-USD_UM-260812-2000-C", "state": "live"}]
|
||||
}
|
||||
first = m.fetch_option_instruments(ex, "ETH-USD_UM")
|
||||
self.assertEqual(len(first), 1)
|
||||
# 过期 TTL,但仍在 stale 窗口
|
||||
with m._INSTRUMENTS_CACHE_LOCK:
|
||||
m._INSTRUMENTS_CACHE["ETH-USD_UM"]["updated_at"] = time.time() - 120
|
||||
ex.public_get_public_instruments.side_effect = Exception(
|
||||
'okx {"msg":"Too Many Requests","code":"50011"}'
|
||||
)
|
||||
second = m.fetch_option_instruments(ex, "ETH-USD_UM")
|
||||
self.assertEqual(len(second), 1)
|
||||
self.assertEqual(second[0]["instId"], "ETH-USD_UM-260812-2000-C")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user