from bson.objectid import ObjectId
from motor.motor_asyncio import AsyncIOMotorClient
import asyncio
a = AsyncIOMotorClient(mongourl)
async def update_one():
print("complete")
return await a[database][collection].insert_one({"_id": ObjectId("61bc40f123a9a9ac317d51c5")},{"a":"b"})
asyncio.run(update_one())
위와 같이 asyncio.run을 시키자 아래와 같은 에러가 발생했다.
과연 이러한 에러는 무엇일까?
일단 구글링 한 결과
loop = asyncio.get_event_loop()
loop.run_until_complete(update_one())
이렇게 get_event_loop를 사용하면 실행이 잘된다.
그렇다면 get_event_loop()와 run()의 차이는 무엇일까?
https://github.com/awestlake87/pyo3-asyncio/issues/19
여기 issue에서 힌트를 얻을 수 있었다.
위의 코드에서 update_one()은 asyncio.run()을 통해 실행이되면 새로운 loop가 나와서 실행되고, AsyncIOMotor()를 통해 데이터베이스에 접근할 때에는 AsyncIOMotor()를 선언할 때 생긴 loop를 이용하기 때문에 이 둘의 loop를 혼용해서 에러가 발생하는 것이다.
그렇지만 여기서 의문인 점이 get_event_loop()를 통해서 나온 loop는 AsyncIOMotor()와 같다는 것인가? 라는 것이다.
그리고 다음 참고자료를 통해 확실시 했다.
위의 자료를 간단히 설명하자면,
get_event_loop를 통해 새롭게 생긴 loop들은 전부 같다. asyncio.run()을 통해 실행시키면 새로운 loop가 생성되고, 끝나면 현재 loop는 None이 된다. 즉, set_event_loop(None)으로 설정한다는 뜻이다. 그렇다면 asyncio.run()을 실행한 뒤에 asyncio.get_event_loop()하면 당연히 에러가 뜬다.
참고로 get_event_loop는 loop를 새롭게 생성하고 계속 선언해도 같은 current loop를 가리키지만, get_running_loop()는 현재 진행되고 있는 loop를 알려준다.
async def main():
loop3 = asyncio.get_running_loop()
print(loop3 is loop1)
await test(loop3)
asyncio.run(main())
위의 코드는 에러가 안생기지만, get_running_loop()가 asyncio.run 이후나 이전에 선언되면 당연히 에러가 생긴다.
loop1 = asyncio.get_event_loop()
loop2 = asyncio.get_event_loop()
# loop1 == loop2
확인해보고싶어서 위 코드를 실행해봤고, 결론적으로 get_event_loop()를 통해 생성된 loop는 다음에 생성해서 현재 loop를 가져온다는 점이고 당연히 같은 loop인 것이다.
그렇다면 AsyncIOMotor가 loop를 생성할 때 get_event_loop()를 통해 생성되면 된다.
https://github.com/mongodb/motor/blob/master/motor/core.py
다음의 github을 봤을 때 get_event_loop를 통해 loop를 가져온다.
asyncio.run()은 되도록 안쓰는것을 추천하는 것 같다. 만약 쓰고싶다면 현재 다른 코루틴 loop가 쓰이고 있는지는 않는지, 다시 loop를 쓰고서 set_event_loop()를 설정해줘야하는지 등등 event loop를 관리를 해줘야한다고 한다.
'Python' 카테고리의 다른 글
python parameter에서 bare *란? (0) | 2022.06.20 |
---|---|
python xxx is not a package (0) | 2022.03.21 |
os.system significantly take time more than shutil. (0) | 2021.12.15 |
(에러)Asyncssh error Host key is not trusted (0) | 2021.11.15 |
python zip folder (0) | 2021.11.15 |