Kerevizde görev durumu nasıl kontrol edilir?


96

Bir görevin kerevizde çalışıp çalışmadığı nasıl kontrol edilir (özellikle kereviz-django kullanıyorum)?

Belgeleri okudum ve Google'da araştırdım, ancak şöyle bir çağrı göremiyorum:

my_example_task.state() == RUNNING

Benim kullanım durumum, kod dönüştürme için harici (java) bir hizmetim olması. Kodu dönüştürülecek bir belge gönderdiğimde, bu hizmeti çalıştıran görevin çalışıp çalışmadığını kontrol etmek ve çalışmıyorsa (yeniden) başlatmak istiyorum.

Mevcut kararlı sürümleri kullanıyorum - 2.4, sanırım.

Yanıtlar:


98

Task_id (.delay () ile verilir) döndürür ve daha sonra kereviz örneğine durumu sorun:

x = method.delay(1,2)
print x.task_id

Sorurken, bu task_id kullanarak yeni bir AsyncResult alın:

from celery.result import AsyncResult
res = AsyncResult("your-task-id")
res.ready()

11
Teşekkürler, ama ya erişimim yoksa x?
Marcin

4
İşlerinizi nerede kereviz haline getiriyorsunuz? Gelecekte işi takip etmek için task_id'yi orada döndürmeniz gerekir.
Gregor

@ Marcin'in aksine, bu yanıt, arka uç yapılandırmasını yararlı bir şekilde yeniden kullanan AsyncResult fabrikası olarak Task.AsyncResult () statik yöntemini kullanmaz, aksi takdirde sonucu almaya çalışırken bir hata oluşur.
ArnauOrriols

2
@Chris @gregor koduyla ilgili tartışma async_result,. Kullanım durumunuzda zaten örneğe sahipsiniz, gitmeniz iyi olur. Ancak, yalnızca görev kimliğiniz varsa ve async_resultçağrı yapabilmek için bir örnek oluşturmanız gerekirse ne olur async_result.get()? Bu, AsyncResultsınıfın bir örneğidir , ancak ham sınıfı kullanamazsınız, sınıfı celery.result.AsyncResultsarılmış işlevden almanız gerekir app.task(). Senin durumunda yapardınasync_result = run_instance.AsyncResult('task-id')
ArnauOrriols

1
but you cannot use the raw class celery.result.AsyncResult, you need to get the class from the function wrapped by app.task(). - Sanırım aslında bu şekilde kullanılması gerekiyordu. Kodu okuyun: github.com/celery/celery/blob/…
nevelis

74

Bir oluşturma AsyncResultgörevi id nesneyi olduğu önerildiği yolu SSS sahip olduğunuz tek şey görev kimliği olduğunda görev statüsü elde etmek.

Ancak Kereviz 3.x itibariyle, dikkat etmezlerse insanları ısırabilecek önemli uyarılar vardır. Gerçekten belirli kullanım senaryosuna bağlıdır.

Varsayılan olarak, Celery bir "çalışma" durumu kaydetmez.

Amacıyla Kereviz bir görev çalıştığını kaydetmesi için, ayarlamanız gerekir task_track_startediçin True. İşte bunu test eden basit bir görev:

@app.task(bind=True)
def test(self):
    print self.AsyncResult(self.request.id).state

Varsayılan değer olan ne zaman task_track_startedolur False, PENDINGgörev başlamış olsa bile durum gösterilir . Eğer ayarlarsanız task_track_startediçin True, o zaman devlet olacaktır STARTED.

Devlet PENDING"bilmiyorum" demektir.

Bir AsyncResultdevlet ile PENDINGdaha Kereviz görevin durumunu bilmiyor daha değil ortalama bir şey yapmıyor. Bunun birçok nedeni olabilir.

Bir kere, AsyncResultgeçersiz görev kimlikleri ile oluşturulabilir. Bu tür "görevler" Kereviz tarafından beklemede sayılacaktır:

>>> task.AsyncResult("invalid").status
'PENDING'

Tamam, yani kimse açıkça geçersiz kimlikleri beslemeyecek AsyncResult. Yeterince adil, ancak aynı zamanda AsyncResultbaşarılı bir şekilde yürütülen ancak Kerevizin unutulmuş bir görevi de dikkate alacak birPENDING etkiye sahiptir . Yine, bazı kullanım durumu senaryolarında bu bir sorun olabilir. Sorunun bir kısmı, Celery'in görevlerin sonuçlarını koruyacak şekilde nasıl yapılandırıldığına bağlıdır, çünkü bu, sonuçların arka ucundaki "mezar taşları" nın kullanılabilirliğine bağlıdır. ( "Mezar taşı" kayıt görevi nasıl bittiğini veri parçaları için Kereviz belgelerinde süreli kullanımıdır.) Kullanılması AsyncResultdurumunda hiç olmaz işi task_ignore_resultolduğunu True. Daha can sıkıcı bir sorun da, Kerevizin varsayılan olarak mezar taşlarının süresinin dolmasıdır. result_expiresayarı varsayılan olarak 24 saate ayarlanmıştır. Bu nedenle, bir görevi başlatırsanız ve kimliği uzun vadeli depolamaya kaydederseniz ve 24 saat sonra onunla bir oluşturursanız AsyncResult, durum olacaktır PENDING.

Tüm "gerçek görevler" PENDINGeyalette başlar. Bu nedenle PENDING, bir göreve başlamak, görevin istendiği ancak hiçbir zaman bundan daha ileriye gitmediği anlamına gelebilir (herhangi bir nedenle). Ya da görevin çalıştığı anlamına gelebilir ama Kereviz durumunu unuttu.

Ah! AsyncResultbenim için çalışmayacak. Başka ne yapabilirim?

Görevleri takip etmektense hedefleri takip etmeyi tercih ederim . Bazı görev bilgilerini saklıyorum ama bu, hedefleri takip etmekten gerçekten ikincil. Hedefler, Kereviz'den bağımsız olarak depoda saklanır. Bir talebin bir hesaplama gerçekleştirmesi gerektiğinde, ulaşılmış bir hedefe bağlı olduğunda, hedefe zaten ulaşılıp ulaşılmadığını kontrol eder, eğer öyleyse, bu önbelleğe alınmış hedefi kullanır, aksi takdirde hedefi etkileyecek görevi başlatır ve HTTP isteğini yapan istemci, bir sonuç için beklemesi gerektiğini belirten bir yanıt.


Yukarıdaki değişken isimleri ve köprüler Celery 4.x içindir. 3.x olarak karşılık gelen değişken ve köprüler şunlardır: CELERY_TRACK_STARTED, CELERY_IGNORE_RESULT, CELERY_TASK_RESULT_EXPIRES.


Yani sonucu daha sonra kontrol etmek istersem (belki başka bir süreçte bile), kendi uygulamamla daha iyi durumdayım? Sonucu veritabanına manuel olarak mı depolamak?
Franklin Yu

Evet, "amaç" takibini "görevleri" takip etmekten ayırırdım. "Bir amaca bağlı olan bir hesaplama yap" yazdım. Genellikle, "amaç" aynı zamanda bir hesaplamadır. Örneğin, X makalesini bir kullanıcıya göstermek istersem, onu XML'den HTML'ye dönüştürmem gerekir, ancak ondan önce tüm bibliyografik referansları çözmüş olmalıyım. (X bir dergi makalesi gibidir.) "Tüm bibliyografik referansları çözülmüş X makalesi" hedefinin var olup olmadığını kontrol ediyorum ve istediğim hedefi hesaplamış olan bir Kereviz görevinin görev durumunu kontrol etmeye çalışmak yerine bunu kullanıyorum.
Louis

Ve "tüm bibliyografik referansları çözülmüş X makalesi" bilgisi bir bellek önbelleğinde saklanır ve bir eXist-db veritabanında saklanır.
Louis

63

Her Tasknesnenin, nesneyi içeren bir .requestözelliği vardır AsyncRequest. Buna göre, aşağıdaki satır bir Görev durumunu verir task:

task.AsyncResult(task.request.id).state

2
Bir görevin ilerleme yüzdesini saklamanın bir yolu var mı?
patrick

5
Bunu yaptığımda, görevin bitmesi için yeterince uzun süre beklesem bile kalıcı olarak PENDING AsyncResult alıyorum. Bunun durum değişikliklerini görmesini sağlamanın bir yolu var mı? Arka ucumun yapılandırıldığına inanıyorum ve CELERY_TRACK_STARTED = Doğru seçeneğini boşuna ayarlamayı denedim.
dstromberg

1
@dstromberg Maalesef bu benim için bir sorun olalı 4 yıl oldu, bu yüzden yardım edemem. Durumu izlemek için kesinlikle kerevizi yapılandırmanız gerekir.
Marcin

@ Dstromberg'in gözlemine ek olarak, sadece doğrulama uğruna, başarılı bir şekilde başarılı olduğunu bildiğim ve statemülkünü kontrol ettiğim bir kereviz görevi aldım , yine de geri döndü PENDING. Bu, terminalden kereviz görevlerinin durumunu takip etmenin güvenilir bir yolu gibi görünmüyor. Ek olarak, Kereviz Çiçeğimi (Kereviz İzleme Aracı) çalıştırıyorum, bazı nedenlerden dolayı aradığım görevleri yerine getirdiği görevler listesinde göstermedi. Geçmişte yalnızca belirli saatlere kadar gösterildiğini söyleyen herhangi bir şey olup olmadığını görmek için Çiçek ayarlarına bakmam gerekebilir.
Derin

16

Ayrıca özel durumlar oluşturabilir ve bunun değerini düşüren görev yürütmesini güncelleyebilirsiniz. Bu örnek, dokümanlardan alınmıştır:

@app.task(bind=True)
def upload_files(self, filenames):
    for i, file in enumerate(filenames):
        if not self.request.called_directly:
            self.update_state(state='PROGRESS',
                meta={'current': i, 'total': len(filenames)})

http://celery.readthedocs.org/en/latest/userguide/tasks.html#custom-states


11

Eski soru ama son zamanlarda bu problemle karşılaştım.

Task_id'yi almaya çalışıyorsanız, bunu şu şekilde yapabilirsiniz:

import celery
from celery_app import add
from celery import uuid

task_id = uuid()
result = add.apply_async((2, 2), task_id=task_id)

Artık task_id'nin tam olarak ne olduğunu biliyorsunuz ve artık AsyncResult'u almak için onu kullanabilirsiniz:

# grab the AsyncResult 
result = celery.result.AsyncResult(task_id)

# print the task id
print result.task_id
09dad9cf-c9fa-4aee-933f-ff54dae39bdf

# print the AsyncResult's status
print result.status
SUCCESS

# print the result returned 
print result.result
4

4
Kendi görev kimliğinizi oluşturmanıza ve bunu iletmenize kesinlikle gerek yoktur apply_async. Tarafından döndürülen nesne, Celery'in oluşturduğu görevin kimliğine sahip olan apply_async bir AsyncResultnesnedir.
Louis

1
Yanılıyorsam düzeltin, ancak bazen aynı girişleri alan tüm aramaların aynı UUID'yi alması için bazı girişlere dayalı bir UUID oluşturmak yararlı olmaz mı? IOW, belki bazen task_id'nizi belirtmek yararlı olabilir.
dstromberg

1
@dstromberg OP tarafından sorulan soru "görev durumunu nasıl kontrol ederim" ve buradaki yanıt "task_id'yi almaya çalışıyorsanız ..." diyor. Ne görev durumunu kontrol etmek, ne de bir görev kimliği oluşturmanızıtask_id gerektirmiyor . Yorumunuzda, "görev durumunu nasıl kontrol ederim" ve "task_id'yi almaya çalışıyorsanız ..." nın ötesine geçen bir neden hayal ettiniz. (Ayrıca, bir görev kimliği oluşturmak için kullanmak , Celery'in varsayılan olarak yaptığının ötesinde kesinlikle hiçbir şey yapmaz.)uuid()
Louis

OP'nin özellikle öngörülebilir görev kimliklerinin nasıl alınacağını sormadığını, ancak OP'nin sorusunun cevabının şu anda "görev kimliğini izle ve x yap" olduğunu kabul ediyorum. Bana öyle geliyor ki, görev kimliğini takip etmek çok çeşitli durumlarda pratik değil, bu yüzden cevap aslında tatmin edici olmayabilir. Bu cevap, kullanım durumumu çözmeme yardımcı oluyor (diğer belirtilen sınırlamaların üstesinden gelebilirsem) @dstromberg'in işaret ettiği aynı nedenden - bu nedenle motive edilip edilmediğine bakılmaksızın.
claytond


1

2020'nin cevabı:

#### tasks.py
@celery.task()
def mytask(arg1):
    print(arg1)

#### blueprint.py
@bp.route("/args/arg1=<arg1>")
def sleeper(arg1):
    process = mytask.apply_async(args=(arg1,)) #mytask.delay(arg1)
    state = process.state
    return f"Thanks for your patience, your job {process.task_id} \
             is being processed. Status {state}"

0

Deneyin:

task.AsyncResult(task.request.id).state

bu, Kereviz Görevi durumunu sağlayacaktır. Kereviz Görevi zaten BAŞARISIZ durumundaysa, bir İstisna oluşturacaktır:

raised unexpected: KeyError('exc_type',)



0

Yararlı bilgiler buldum

İşçileri teftiş eden Kereviz Projesi İşçileri Kılavuzu

Benim durumum için, Kereviz çalışıp çalışmadığını kontrol ediyorum.

inspect_workers = task.app.control.inspect()
if inspect_workers.registered() is None:
    state = 'FAILURE'
else:
    state = str(task.state) 

İhtiyaçlarınızı karşılamak için inspect ile oynayabilirsiniz.


0
  • İlk olarak kereviz uygulamanızda :

vi my_celery_apps / app1.py

app = Celery(worker_name)
  • ve sonra, kereviz uygulama modülünüzden görev dosyasına gidin , uygulamayı içe aktarın.

vi görevler / görev1.py

from my_celery_apps.app1 import app

app.AsyncResult(taskid)

try:
   if task.state.lower() != "success":
        return
except:
    """ do something """


-1

Yukarıdakilerin yanı sıra Programlı yaklaşım Flower Task'ın kullanılması durumu kolayca görülebilir.

Celery Events kullanarak gerçek zamanlı izleme. Flower, Kereviz kümelerini izlemek ve yönetmek için web tabanlı bir araçtır.

  1. Görev ilerlemesi ve geçmişi
  2. Görev ayrıntılarını gösterme yeteneği (bağımsız değişkenler, başlangıç ​​zamanı, çalışma zamanı ve daha fazlası)
  3. Grafikler ve istatistikler

Resmi Belge: Çiçek - Kereviz izleme aracı

Kurulum:

$ pip install flower

Kullanım:

http://localhost:5555

-1
res = method.delay()
    
print(f"id={res.id}, state={res.state}, status={res.status} ")

print(res.get())

2
Lütfen yanıt olarak yalnızca kod göndermeyin, aynı zamanda kodunuzun ne yaptığını ve sorunun sorununu nasıl çözdüğünü de açıklayın. Açıklamalı yanıtlar genellikle daha yararlıdır ve daha kalitelidir ve olumlu oyları alma olasılığı daha yüksektir.
Mark Rotteveel
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.