discord.ext.tasks
– asyncio.Task 헬퍼¶
버전 1.1.0에 추가.
봇을 만들 때 하는 가장 흔한 작업은 특정한 간격으로 백그라운드에서 돌아가는 루프를 갖는 것입니다. 이 패턴은 매우 흔하지만 당신이 조심해야할 많은 것들이 있습니다:
asyncio.CancelledError
는 어떻게 다루나요?만약에 인터넷이 끊기면 어떻게 해야하나요?
아무튼 제가 잘 수 있는 최고 시간은 몇초인가요?
이 discord.py 확장의 목적은 이런 관념적인 걱정들을 덜어주는 것입니다.
레시피¶
Cog
에서의 간단한 백그라운드 태스크:
from discord.ext import tasks, commands
class MyCog(commands.Cog):
def __init__(self):
self.index = 0
self.printer.start()
def cog_unload(self):
self.printer.cancel()
@tasks.loop(seconds=5.0)
async def printer(self):
print(self.index)
self.index += 1
재연결 중 발생하는 예외를 처리하기 위해 예외 추가:
import asyncpg
from discord.ext import tasks, commands
class MyCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.data = []
self.batch_update.add_exception_type(asyncpg.PostgresConnectionError)
self.batch_update.start()
def cog_unload(self):
self.batch_update.cancel()
@tasks.loop(minutes=5.0)
async def batch_update(self):
async with self.bot.pool.acquire() as con:
# batch update here...
pass
종료하기 전에 특정 개수만큼 반복:
from discord.ext import tasks
@tasks.loop(seconds=5.0, count=5)
async def slow_count():
print(slow_count.current_loop)
@slow_count.after_loop
async def after_slow_count():
print('done!')
slow_count.start()
루프를 시작하기 전에 봇이 준비되기 전까지 기다림:
from discord.ext import tasks, commands
class MyCog(commands.Cog):
def __init__(self, bot):
self.index = 0
self.bot = bot
self.printer.start()
def cog_unload(self):
self.printer.cancel()
@tasks.loop(seconds=5.0)
async def printer(self):
print(self.index)
self.index += 1
@printer.before_loop
async def before_printer(self):
print('waiting...')
await self.bot.wait_until_ready()
취소하는 동안 무언가를 하기:
from discord.ext import tasks, commands
import asyncio
class MyCog(commands.Cog):
def __init__(self, bot):
self.bot= bot
self._batch = []
self.lock = asyncio.Lock()
self.bulker.start()
async def do_bulk(self):
# bulk insert data here
...
@tasks.loop(seconds=10.0)
async def bulker(self):
async with self.lock:
await self.do_bulk()
@bulker.after_loop
async def on_bulker_cancel(self):
if self.bulker.is_being_cancelled() and len(self._batch) != 0:
# if we're cancelled and we have some data left...
# let's insert it to our database
await self.do_bulk()
API 레퍼런스¶
- async__call__
- defadd_exception_type
- @after_loop
- @before_loop
- defcancel
- defchange_interval
- defclear_exception_types
- @error
- deffailed
- defget_task
- defis_being_cancelled
- defis_running
- defremove_exception_type
- defrestart
- defstart
- defstop
-
class
discord.ext.tasks.
Loop
¶ 당신을 위해 루프와 재연결 로직을 추상화하는 백그라운드 태스크 헬퍼.
이것을 생성하는 주요 인터페이스는
loop()
를 통한 것입니다.-
next_iteration
¶ 루프의 다음 반복이 일어날 때
버전 1.3에 추가.
- 형식
-
await
__call__
(*args, **kwargs)¶ 이 함수는 코루틴 입니다.
Calls the internal callback that the task holds.
버전 1.6에 추가.
- 매개변수
*args – 사용할 전달인자.
**kwargs – 사용할 키워드 전달인자.
-
start
(*args, **kwargs)¶ 이벤트 루프에서 내부 태스크를 시작합니다.
- 매개변수
*args – 사용할 전달인자.
**kwargs – 사용할 키워드 전달인자.
- 예외
RuntimeError – 태스크가 이미 시작되었고 실행되는 중입니다.
- 반환값
생성된 태스크.
- 반환 형식
-
stop
()¶ 돌아가는 태스크를 중지합니다.
cancel()
과는 달리, 태스크를 중지하기 전에 현재 반복 중인 것을 완료하게 만듭니다.참고
만약 내부 함수가 끝내기 전에 처리할 수 있는 오류를 일으켰다면 성공할 때 까지 재시도할 것입니다.
만약에 이것을 원하지 않는다면,
clear_exception_types()
로 멈추기 전에 오류 처리를 제거하거나cancel()
을 대신 사용해주세요.버전 1.2에 추가.
-
cancel
()¶ 약 내부 태스크가 돌아가고 있다면 취소함.》
-
restart
(*args, **kwargs)¶ 내부 태스크를 재시작하기 위한 편리한 방법.
참고
이 함수가 작동하는 방식 때문에,
start()
처럼 태스크가 반환되지 않습니다.- 매개변수
*args – 사용할 전달인자.
**kwargs – 사용할 키워드 전달인자.
-
add_exception_type
(*exceptions)¶ 재연결 로직 도중 처리돼야 하는 예외 형식들을 추가합니다.
기본 상태에서는 처리되는 예외 형식들은
discord.Client.connect()
로 처리되는데, 많은 인터넷 연결 끊어짐 오류를 포함하고 있습니다.만약에 자기만의 예외 집합을 일으키는 제 3자 라이브러리와 상호 작용하고 있다면 이 함수는 유용합니다.
- 매개변수
*exceptions (Type[
BaseException
]) – 처리해야 할 예외 클래스들의 전달인자 리스트.- 예외
TypeError – 지나간 예외는 클래스가 아니거나
BaseException
에서 상속되지 않았습니다.
-
clear_exception_types
()¶ 처리 가능한 모든 형식의 예외를 삭제합니다.
참고
이 작업은 당연히 되돌릴 수 없습니다!
-
remove_exception_type
(*exceptions)¶ 재연결 로직 도중 처리돼야 하는 예외 형식들을 삭제합니다.
- 매개변수
*exceptions (Type[
BaseException
]) – 처리해야 할 예외 클래스들의 전달인자 리스트.- 반환값
모든 예외가 성공적으로 삭제되었는지의 여부.
- 반환 형식
-
get_task
()¶ 옵션[
asyncio.Task
]: 내부 테스크를 가져오거나 아무것도 돌아가고 있지 않는다면None
을 반환합니다.
-
is_being_cancelled
()¶ 태스크가 취소되고 있는지의 여부.
-
before_loop
(coro)¶ 루프가 시작되기 전에 코루틴이 호출되도록 등록하는 데코레이터.
만약에
discord.Client.wait_until_ready()
처럼 루프가 시작되기 전에 몇가지 봇 상태가 기다리도록 만들고 싶다면 유용합니다.코루틴은 (클래스 컨택스트 내부에 있는
self
를 제외하고) 그 어떤 전달인자도 갖고 있으면 안됩니다.
-
after_loop
(coro)¶ 루프가 끝난 이후 코루틴이 호출되도록 등록하는 데코레이터.
코루틴은 (클래스 컨택스트 내부에 있는
self
를 제외하고) 그 어떤 전달인자도 갖고 있으면 안됩니다.참고
이 코루틴은 취소할때도 호출됩니다. 만약에 무언가가 취소되었는지 아닌지를 분리해야 한다면,
is_being_cancelled()
가True
인지 아닌지를 확인하세요.
-
error
(coro)¶ 만약 테스크가 처리되지 않은 예외를 만났을 경우 호출될 코루틴을 등록하는 데코레이터.
코루틴은 (클래스 컨택스트 내부에 있는
self
를 제외하고) 발생한 예외 전달인자 하나만을 가져야 합니다.기본 상태에서는
sys.stderr
로 출력하지만 다른 구현을 가지기 위해 무시될 수 있습니다.버전 1.4에 추가.
-
-
discord.ext.tasks.
loop
(*, seconds=0, minutes=0, hours=0, count=None, reconnect=True, loop=None)¶ 재연결 로직 옵션과 백그라운드에서 태스크를 예약하는 데코레이터. 데코레이터는
Loop
를 반환합니다.- 매개변수
seconds (
float
) – 모든 반복 사이의 초.minutes (
float
) – 모든 반복 사이의 분.hours (
float
) – 모든 반복 사이의 시간.count (Optional[
int
]) – 루프의 반복 횟수, 만약에 무한 반복이어야 한다면None
.reconnect (
bool
) –discord.Client.connect()
에 사용된 것처럼 기하급수적인 백오프 알고리즘으로 오류를 처리하거나 태스크를 재시작할지의 여부loop (
asyncio.AbstractEventLoop
) – 태스크를 등록하기 위해 사용하는 루프, 만약에 주어지지 않았다면 기본으로asyncio.get_event_loop()
.
- 예외
ValueError – 잘못된 값이 주어졌습니다.
TypeError – 함수가 코루틴이 아닙니다.