2012-07-12 2 views
5

기본 Django 애플리케이션 프로세스에서 셀러리 작업의 결과에 액세스하려면 어떻게해야합니까? 아니면 별도의 프로세스에서 기존 소켓 연결에 게시 할 수 있습니까?django-socketio with Celery : 비동기 작업이 별도의 프로세스로 완료되면 소켓으로 보냅니다.

사용자가 점수를받는 응용 프로그램이 있습니다. 점수가 기록되면 계산이 수행되고 (목표를 향한 진행 등), 계산에 따라 관심있는 사용자에게 알림이 전송됩니다. 계산은 30 초 이상 걸릴 수 있습니다. 따라서 부진한 UI를 피하기 위해 셀로리 작업을 통해 백그라운드 작업에서 작업을 수행합니다.이 작업은 내 점수 모델의 post_save 신호에 의해 호출됩니다.

내 Nofication 모델의 post_save 신호는 구독 클라이언트 (gevent-socketio의 래퍼 인 django-socketio를 사용하고 있습니다)에게 메시지를 게시하는 것이 이상적입니다. 이

  1. 통지에 저장 잡아 신고서를 백그라운드 프로세스 그 계산을 바탕으로
  2. 의 새로운 점수 인스턴스에 대한 몇 가지 계산을 수행합니다 점수
  3. 을 만들기 ... 간단 보인다 인스턴스이 가능 잘 모르겠어요 다음을 시도한 후

그러나 소켓 연결을 통해 가입 한 고객에 게시 :

  • 작업에 의해 호출 된 콜백 메소드에 gevent의 SocketIOServer 인스턴스를 전달하지만이

  • memchache과 (장고의 SESSION_ID 다른) 소켓의 SESSION_ID를 저장 할 수 없습니다 전달 된 객체를, 산세 필요 셀러리 작업 프로세스에서이를 검색합니다.

  • Redis pubsub를 사용하여 백그라운드 프로세스에서 생성 된 모델의 post_save 신호로 호출되는 메소드는 단순히 Redis 채널로 퍼블리싱 할 수 있지만 주 애플리케이션 프로세스 (소켓 연결에 대한 액세스 권한 있음)에서 채팅 채널을 수신하면 나머지 응용 프로그램.

  • 또한 각 소켓 가입자를 위해 생성 된 각 Redis 클라이언트에 대해 새 스레드를 생성하려고했습니다. 지금까지 내가 말할 수있는이 새로운 gevent.greenlets.Greenlet 산란이 필요하며, gevent 여러 스레드

에서 사용할 수 없습니다 확실히이 해결 된 문제입니다. 내가 뭘 놓치고 있니?

+1

일부 코드를 표시 할 수 있습니까?요구 사항이 있지만 구현 시도가 명확하지 않습니다. 이 파일 구조를 사용한다고 가정 할 때 tasks.py와 views.py는 어떻게 생겼을까요? –

+0

socketio 처리기가 서버에서 시작될 때, 그들은 무엇을합니까? 그들은 redis pub-sub queue에 가입합니까? 그렇다면 redis-py gevent monkeypatch를 사용하고 있습니까? 당신의 어딘가에이 라인을 넣어야합니다 :'import redis, gevent; redis.connection.socket = gevent.socket' https://github.com/andymccurdy/redis-py/pull/199. 이해해야 할 것은 socketio 핸들러와 같은 지렁이 같은 그린 레트가 여러분이 패치 된 소켓/파일 설명자를 사용하지 않는다면 여전히 프로세스를 차단한다는 것입니다. – Thomas

답변

0

이미 유감 :) 것 레디 스와 함께 술집/하위를 작성, 장고 - socketio이

클라이언트 측 :

var socket = new io.Socket(); 
socket.connect(); 
socket.on('connect', function() { 
    socket.subscribe({{ score_update_channel }}); 
}); 

서버 측 : 당신이 필요로하는

from django_socketio import broadcast_channel 
def user_score_update(user): 
    return 'score_updates_user_%s' % user.pk 

channel = user_score_update(user) 
broadcast_channel(score_result_data, channel) 

django-socketio 프로세스에서 브로드 캐스트를 실행하려면; 다른 프로세스 (셀러리 작업자)에서 실행하면 작동하지 않습니다 (채널은 django-socketio 프로세스에 의해 메모리에서 참조됩니다). 보기에서 셀을 감싸서 해결할 수 있으며 작업이 완료되면 셀러리가 (실제 http 요청을 작성하여) 호출합니다.

관련 문제