2016-05-30 13 views
3

私はInstagramを模倣したDjangoアプリを持っており、写真やムービーをアップロードしてファンにその写真を通知します。Celeryを使ってDjangoでタスクを非同期的に実行する正しい方法

現在、通知を送信するために、ユーザーが写真をアップロードするとすぐに、アップロード者が持っているすべてのファンを繰り返し、通知をリストに追加してからbulk_createオブジェクトに追加します。次のように:

fans = UserFan.objects.filter(star=user).values_list('fan',flat=True) 
    fan_list = [] 
    for fan in fans: 
     fan_list.append(PhotoObjectSubscription(viewer_id=fan, which_photo=photo, updated_at=time, seen=False, type_of_object='1')) 
    PhotoObjectSubscription.objects.bulk_create(fan_list) 

シンプルなもの。私もsupervisordを私のアプリケーションのVMにインストールしました。ここでは、celery(メッセージブローカーとしてredis)経由でいくつかの基本タスクを実行します。

ここでは、上記のbulk_createタスクをcelery taskとして実行します。非同期に。私のbulk_createコードは、写真のアップロードを処理するために使用されるビューと同じビューに存在するため、非同期に処理すると、そのプロセスがスピードアップします。

私はceleryタスクに新しくなっています。したがって、上記のbulk_createタスクをceleryタスクにどのように変えることができるのか説明できる例がありますか?私は研究を行って、そしてここで私は私が行う必要があると思う何ました:

1)bulk_create文の末尾にdelay()を追加します:tasks.py

PhotoObjectSubscription.objects.bulk_create(fan_list).delay() 

2)、プロセスに新しいタスクを追加します上記:

@task 
def bulk_create_notifications(): 
    PhotoObjectSubscription.objects.bulk_create(fan_list) 

3)タスクが定期的な作業ではありませんから、settings.pyCELERYBEAT_SCHEDULEに何も追加する必要はありません。

私はおそらく完全に正確ではないので、助けてください。

答えて

3

タスクに引数として(例えばphoto.id)タスクのニーズをfansを渡す必要があります(あなたはそれが実際にValuesListQuerySetある場合listにキャストする必要がある場合があります)と、他のすべてのもの:

@task 
def bulk_create_notifications(fans, photo_id): 
    fan_list = [] 
    for fan in fans: 
     fan_list.append(PhotoObjectSubscription(viewer_id=fan, which_photo_id=photo_id, updated_at=time, seen=False, type_of_object='1')) 
    PhotoObjectSubscription.objects.bulk_create(fan_list) 

引数は、あなたのタスクキュー(Redisの)によって保存され、通信する必要があるので、あなただけのシリアライザあなたによって、シリアライズされている引数を渡すことができ

# call delay on the task and pass it the same params you would pass to the fnc itself 
bulk_create_notifications.delay(fans) 

:次に、あなたは非同期経由でタスクを開始することができますあなたの設定(おそらくJSON)に設定されています。つまり、単純なタイプのs.aに固執する必要があります。文字列、整数であり、モデルインスタンスまたはそのリストをパラメータとして渡すことはできません。

もちろん、さらに高い値から始めて、user.idを渡して、すべてのdb作業をタスク内で行うことができます。

+0

いいえ、あなたのコードを誤読していました。私はすでに答えでそれを変更しました。モデルインスタンスを渡すことはできません!あなたのdev envでCELERY_ALWAYS_EAGERが 'True'に設定されているときにうまく動作するかもしれませんが、実際にはパラメータがキューを通過してしまいます。 – schwobaseggl

+0

@HassanBaig実際には、あなたのコードの 'fans'は' ListList'にキャストしてタスクに渡す 'ValuesListQuerySet'です。 – schwobaseggl

+0

私はこれを試して、ちょっとあなたに戻ってきます! –

関連する問題