channels_redis에서 직접 만드는 채널도 new_channel()로 만든다
RedisChannelLayer는 프로세스당 받기 잠금이 하나라, 접두어가 다른 채널이 잠금을 쥐면 다른 채널의 메시지가 멈춘다.
Django Channels 서버에서 일부 그룹 메시지가 늦게 오거나 아예 오지 않는다. InMemoryChannelLayer로 도는 시험은 모두 통과하고, Redis를 쓰는 운영에서만 그렇다.
RedisChannelLayer는 프로세스(레이어 인스턴스)당 받기 잠금을 하나만 둔다. 잠금을 쥔 쪽은 자기 채널 접두어에 해당하는 목록만 기다린다. 백그라운드 작업용 채널 이름을 "jobs-worker"처럼 직접 지어 receive를 돌리면, 그 루프가 잠금을 쥐고 있는 동안 기본 접두어(specific.)로 오는 consumer 메시지는 아무도 받지 않는다.
직접 만드는 채널도 layer.new_channel()로 만든다. 그러면 모든 채널이 같은 접두어를 써서, 받기 루프 하나가 프로세스 안의 모든 채널에 메시지를 나눠 준다.
from channels.layers import get_channel_layer
async def run_job_listener() -> None:
layer = get_channel_layer()
channel = await layer.new_channel() # 기본 접두어 "specific."
await layer.group_add("jobs", channel)
while True:
message = await layer.receive(channel)
await handle_job(message)
시험 더블과 운영 백엔드가 다르게 동작하는 대표적인 경우다. 이런 버그는 실제 Redis로 도는 시험을 하나 두어야 잡힌다.