2017-08-07 3 views
0

私はhttp rest callから取得したデータをユーザーに更新するdiscord botを作成しようとしています。asycioバックグラウンドスレッドでaiohttpを使用する方法

discord.pyはasyncioを使用しているので、私はこのアプローチに従うことを試みると思いました。

async def my_background_task(): 

    print("starting BG task") 
    await client.wait_until_ready() 
    while not client.is_closed: 
     requests.get(getMyUrl()).json()["dict_element"] 
     #do more stuff 

client.loop.create_task(my_background_task()) 
client.run("api key goes here") 

同期「リクエスト」ライブラリを使用すれば十分です。しかし、私はそれがクラッシュするまで、約2,3時間実行することができます。私は、「要求」が無限ループを終わらせることに失敗したためだと思います。

async def fetch(session, url): 
    async with session.get(url) as resp: 
     print(resp.status) 
     return await resp 

async def fetch_url(loop, url): 
    async with aiohttp.ClientSession(loop=loop) as session: 
     await fetch(session, url) 

async def my_method(url): 

    loop = asyncio.get_event_loop() 
    return loop.run_until_complete(fetch_url(loop,url)) 

async def my_background_task(): 

    print("starting BG task") 
    await client.wait_until_ready() 
    while not client.is_closed: 
     await my_method.("www.theinternet.com/restcall").json()["dict_element"] 
     #do more stuff 

このように、私は今、aiohttpを使って作業しようとしていますが、このループ内の非同期ループに関する問題にぶつかります。

私はこれにアプローチする方法について適切な説明が見つかりませんでした。私はかなりPythonと非同期関数の新機能です。

答えて

0

私は、http応答をグローバル変数として保持し、それをそれ自身で更新する別のバックグラウンドタスクを持っています。

それは私がそれをやるべき方法であるかどうかはわかりませんが、それがピクルから私を奪ったものです。

1

あなたのaiohttpバージョンからエラーが出ることなく、推測するのは難しいです。しかし、一見、私はそれを言う:

  • ClientSessionに明示的にイベントループに合格する必要はありませんが、ないはずそれは自動的に現在のイベントループを選択しますので、あなただけの​​
  • fetch関数を呼び出す必要がありますawait resprespはコルーチンではありません。あなたはおそらくmy_method
  • return await resp.json()したい(とmy_background_task内の余分な.json()を除く)async defによって示されるように、あなたはすでに、コルーチンで実行されています。したがって、別のコルーチンを呼び出すには、awaitとする必要があります。新しいイベントループを作成せずに、その新しいループで実行する必要があります。
  • my_background_taskで、あなたは何らかの意味をなさないものを待っています:awaitのオペレータ優先度を確認し、コルーチンで.__getitem__を呼び出してから、結果を待って__getitem__を返します。
  • また、その行では、応答が閉じられた後に応答のjson本体を読み取ろうとすることはできません(async withを終了するとすぐに応答が閉じられます。つまり、fetchメソッドが完了するとすぐに終了します)。
  • 最後に、すべてのループでClientSessionを再作成しないでください。それはリクエスト間で共有できるように、これは存在するので、あなたはmy_background_taskに一度、それを作成して使用する必要があり、それ

-

async def fetch(session, url): 
    async with session.get(url) as resp: 
     print(resp.status) 
     return await resp.json() 

async def my_background_task() 
    print("starting BG task") 
    await client.wait_until_ready() 
    async with aiohttp.ClientSession() as session: 
     while not client.is_closed: 
      data = await fetch(session, "www.theinternet.com/restcall") 
      element = data["dict_element"] 
関連する問題