У меня есть простой класс для извлечения URL-адресов при периодическом обновлении токена доступа с использованием нового цикла в отдельном потоке:
import asyncio
import aiohttp
from threading import Thread
from random import randint
LOOP = asyncio.get_event_loop()
NEW_LOOP = asyncio.new_event_loop()
t = Thread(target=NEW_LOOP.run_forever)
t.start()
class SOME_CLASS(object):
def __init__(self, loop=LOOP, new_loop=NEW_LOOP):
self.token = None
self.loop = loop
self.new_loop = new_loop
self.semaphore = asyncio.Semaphore(3)
self.session = aiohttp.ClientSession(loop=self.loop)
asyncio.run_coroutine_threadsafe(self.get_token(), self.new_loop)
def _get_headers(self):
headers = {
'x-access-token': str(self.token),
'content-type': 'application/json',
}
return headers
async def get_token(self):
while True:
self.token = randint(1, 100)
await asyncio.sleep(2)
async def fetch(self, url):
async with self.semaphore:
headers = self._get_headers()
async with self.session.get(url, headers=headers) as response:
await response.read()
return headers
async def fetch_all(self):
urls = ['https://httpbin.org/get?x={i}'for i in range(1000)]
futures = asyncio.as_completed([self.fetch(url) for url in urls])
for future in futures:
await asyncio.sleep(1)
headers = await future
print(f'headers: {headers} token: {self.token}')
def run(self):
self.loop.run_until_complete(self.fetch_all())
if __name__ == '__main__':
sc = SOME_CLASS()
sc.run()
Однако я заметил, что хотя self.token
действительно обновляется каждый раздве секунды токен, сохраненный в headers
, остается неизменным.Кажется, что self._get_headers()
вызывается заблаговременно, а не после того, как он получает семафор:
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 8
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 8
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 78
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 78
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 41
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 56
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 56
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 74
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 74
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 4
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 4
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 10
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 10
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 44
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 44
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 28
headers: {'x-access-token': '8', 'content-type': 'application/json'} token: 28
Как мне убедиться, что токен действительно обновляется в headers
прямо перед запросом httpотосланный?