Celery: Mencabut/Membatalkan tugas saat pekerja dimatikan

Dibuat pada 24 Feb 2016  ·  3Komentar  ·  Sumber: celery/celery

Saya menggunakan 3.1.20 (broker Redis dan backend) dan saya ingin cara untuk Membatalkan/Mencabut tugas yang sedang berjalan saat pekerja sedang dimatikan.
Intinya adalah untuk menandai tugas sebagai GAGAL jika memungkinkan, dan tidak menjalankannya kembali saat pekerja memulai lagi.

Saya menjalankan satu tugas pada satu waktu dan karena tugas tersebut memiliki efek samping (dan saya tidak dapat mengubahnya), membunuh pekerja akan menjadi perilaku pengguna yang diharapkan ketika terjadi kesalahan, dan saya tidak ingin tugas tersebut dijalankan kembali berikutnya waktu saya memulai pekerja (perilaku sighandler default saya percaya ...)

Saya telah mencoba http://stackoverflow.com/a/8230470 tanpa hasil.
Dan saya juga mencoba beberapa hal menggunakan antarmuka kontrol atau pekerja dari bootstep :

from celery import Celery, bootsteps
from celery.task.control import revoke

# TODO : configuration for tests...
class BootPyrosNode(bootsteps.StartStopStep):

    def __init__(self, worker, **kwargs):
        logging.warn('{0!r} is starting from {1}'.format(worker, __file__))

        [...]

    def create(self, worker):
        return self

    def start(self, worker):
        # our step is started together with all other Worker/Consumer
        # bootsteps.
        pass  # not sure in which process this is run.

    def stop(self, worker):
        # the Consumer calls stop every time the consumer is restarted
        # (i.e. connection is lost) and also at shutdown.  The Worker
        # will call stop at shutdown only.
        logging.warn('{0!r} is stopping. Attempting abort of current tasks...'.format(worker))
        for req in worker.state.active_requests:
            # worker.app.control.revoke(req.id, terminate=True) # not working
            # revoke(req.id, terminate=True) # not working
        self.node_proc.shutdown()

dipasang dengan cara ini:

celeros_app = Celery()

# setting up custom bootstep to start ROS node and pass ROS arguments to it
celeros_app.steps['worker'].add(BootPyrosNode)
celeros_app.user_options['worker'].add(Option('-R', '--ros-arg', action="append", help='Arguments for ros initialisation'))

Namun sepertinya tugas saya tidak dapat dicabut/dibatalkan, (mungkin karena pekerja tidak memproses pesan kontrol setelah berhenti?) dan saya kehabisan ide.

Jika Anda ingin melihat lebih banyak, kodenya berasal dari: https://github.com/asmodehn/celeros.

Apakah ada cara, atau apakah ini penyesuaian yang belum memungkinkan?

Feature Request

Komentar yang paling membantu

Terima kasih !
Saya berhasil mencabut tugas yang sedang berjalan pada shutdown pekerja. :

def stop(self, worker):
        # the Consumer calls stop every time the consumer is restarted
        # (i.e. connection is lost) and also at shutdown.  The Worker
        # will call stop at shutdown only.
        logging.warn('{0!r} is stopping. Attempting termination of current tasks...'.format(worker))

        # Following code from worker.control.revoke

        task_ids = []
        terminated = set()

        # cleaning all reserved tasks since we are shutting down
        signum = _signals.signum('TERM')
        for request in [r for r in worker.state.reserved_requests]:
            if request.id not in terminated:
                task_ids.append(request.id)
                terminated.add(request.id)
                logger.info('Terminating %s (%s)', request.id, signum)
                request.terminate(worker.pool, signal=signum)

        # Aborting currently running tasks, and triggering soft timeout exception to allow task to clean up.
        signum = _signals.signum('USR1')
        for request in [r for r in worker.state.active_requests]:
            if request.id not in terminated:
                task_ids.append(request.id)
                terminated.add(request.id)
                logger.info('Terminating %s (%s)', request.id, signum)
                request.terminate(worker.pool, signal=signum)  # triggering SoftTimeoutException in Task

        if terminated:
            terminatedstr = ', '.join(task_ids)
            logger.info('Tasks flagged as revoked: %s', terminatedstr)

        self.node_proc.shutdown()

Pertama saya mencabut tugas dalam daftar reserved_requests untuk pada dasarnya mencegah tugas menunggu mengambil alih sebelum shutdown.

Kemudian saya mencabut permintaan aktif, dan kemudian saya memicu pengecualian SoftTimeLimitExceeded dalam tugas untuk dapat memicu perilaku pembersihan dalam tugas. Karena saya menggunakan acks_late ( untuk menjalankan hanya satu tugas pada satu waktu), saya harus kembali atau naik dari tugas untuk mengakuinya dengan benar dan tidak memulai ulang saat berikutnya saya meluncurkan pekerja.

Saya menggunakan tugas yang dapat dibatalkan, tetapi perilaku pembatalan dikodekan ketika pengguna ingin secara sadar membatalkan tugas, dan sistem perlu melakukan pembersihan yang rumit/panjang. Kasus ini lebih seperti pekerja yang dimatikan, dan dalam hal ini saya ingin membuat tugas saat ini gagal dengan cepat.

Saya pikir ini akan menjadi cara yang tepat untuk melakukan sesuatu di seledri?

Dalam versi yang akan datang, akan menyenangkan untuk dapat mendefinisikan ulang perilaku di kelas Tugas... misalnya membebani metode on_revoke() atau on_abort(). Dan mungkin cara untuk memiliki banyak perilaku saat dicabut, tergantung pada beberapa kondisi ...
Hanya 2 sen saya, saya belum memeriksa seledri v4.0.

Semua 3 komentar

Anda tidak dapat mengirim perintah remote control ke diri Anda sendiri selama shutdown, Anda perlu mencabut tugas menggunakan internal pekerja (lihat bagaimana perintah remote control diimplementasikan di celery/worker/control.py).

Anda mungkin juga harus memastikan bootstep Anda bergantung pada Pool, sehingga metode stop() Anda dipanggil terlebih dahulu selama shutdown:

class Step..:
    requires = ('celery.worker.components:Pool',)

Terima kasih !
Saya berhasil mencabut tugas yang sedang berjalan pada shutdown pekerja. :

def stop(self, worker):
        # the Consumer calls stop every time the consumer is restarted
        # (i.e. connection is lost) and also at shutdown.  The Worker
        # will call stop at shutdown only.
        logging.warn('{0!r} is stopping. Attempting termination of current tasks...'.format(worker))

        # Following code from worker.control.revoke

        task_ids = []
        terminated = set()

        # cleaning all reserved tasks since we are shutting down
        signum = _signals.signum('TERM')
        for request in [r for r in worker.state.reserved_requests]:
            if request.id not in terminated:
                task_ids.append(request.id)
                terminated.add(request.id)
                logger.info('Terminating %s (%s)', request.id, signum)
                request.terminate(worker.pool, signal=signum)

        # Aborting currently running tasks, and triggering soft timeout exception to allow task to clean up.
        signum = _signals.signum('USR1')
        for request in [r for r in worker.state.active_requests]:
            if request.id not in terminated:
                task_ids.append(request.id)
                terminated.add(request.id)
                logger.info('Terminating %s (%s)', request.id, signum)
                request.terminate(worker.pool, signal=signum)  # triggering SoftTimeoutException in Task

        if terminated:
            terminatedstr = ', '.join(task_ids)
            logger.info('Tasks flagged as revoked: %s', terminatedstr)

        self.node_proc.shutdown()

Pertama saya mencabut tugas dalam daftar reserved_requests untuk pada dasarnya mencegah tugas menunggu mengambil alih sebelum shutdown.

Kemudian saya mencabut permintaan aktif, dan kemudian saya memicu pengecualian SoftTimeLimitExceeded dalam tugas untuk dapat memicu perilaku pembersihan dalam tugas. Karena saya menggunakan acks_late ( untuk menjalankan hanya satu tugas pada satu waktu), saya harus kembali atau naik dari tugas untuk mengakuinya dengan benar dan tidak memulai ulang saat berikutnya saya meluncurkan pekerja.

Saya menggunakan tugas yang dapat dibatalkan, tetapi perilaku pembatalan dikodekan ketika pengguna ingin secara sadar membatalkan tugas, dan sistem perlu melakukan pembersihan yang rumit/panjang. Kasus ini lebih seperti pekerja yang dimatikan, dan dalam hal ini saya ingin membuat tugas saat ini gagal dengan cepat.

Saya pikir ini akan menjadi cara yang tepat untuk melakukan sesuatu di seledri?

Dalam versi yang akan datang, akan menyenangkan untuk dapat mendefinisikan ulang perilaku di kelas Tugas... misalnya membebani metode on_revoke() atau on_abort(). Dan mungkin cara untuk memiliki banyak perilaku saat dicabut, tergantung pada beberapa kondisi ...
Hanya 2 sen saya, saya belum memeriksa seledri v4.0.

ada update tentang ini?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat