django-carrot service

Carrot implements two manage.py commands in your django app - carrot and carrot_daemon

The carrot command is the base service which starts consuming messages from your defined RabbitMQ brokers, and publishing any active scheduled tasks at the required intervals

carrot_daemon is a daemon which can be used the invoke the carrot service as a detached process, and allows users to stop/restart the service safely, and to check the status. carrot_daemon can be invoked as follows:

python manage.py carrot_daemon start
python manage.py carrot_daemon stop
python manage.py carrot_daemon restart
python manage.py carrot_daemon status

Further options

The following additional arguments are also available:

–logfile:path to the log file. Defaults to /var/log/carrot.log
–pidfile:path to the pid file. Defaults to /var/run/carrot.pid
–no-scheduler:run the carrot service without the scheduler (only consumes tasks)
–testmode:Used for running the carrot tests. Not applicable for most users
–loglevel:The level of logging to use. Defaults to DEBUG and shouldn’t be changed under most circumstances

examples

Custom log/pid file paths

On some systems you may encounter OS errors while trying to run the service with the default log/pid file locations. This can be fixed by specifying your own values for these paths:

python manage.py carrot_daemon start --logfile carrot.log --pidfile carrot.pid

Warning

If you use a custom pid, you must also provide this same argument when attempting to stop, restart or check the status of the carrot service

Running without the scheduler

Use the following to disabled ScheduledTasks

python manage.py carrot_daemon --no-scheduler

Debugging

Using the carrot_daemon will run in detached mode with no sys.out visible. If you are having issues getting the service working properly, or want to check your broker configuration, you can use the carrot command instead, as follows:

python manage.py carrot

You will be able to read the system output using this command, which should help you to resolve any issues

Note

The carrot command does not accept the pidfile or mode (e.g. start, stop, restart, status) arguments. No pid file gets created in this mode, and the process is the equivalent of carrot_daemon start. To stop the process, simply use CTRL+C

Classes and methods

class carrot.management.commands.carrot_daemon.Command(stdout=None, stderr=None, no_color=False)

The daemon process for controlling the carrot.management.commands.carrot service

add_arguments(parser)

This Command inherits the same arguments as carrot.management.commands.carrot.Command, with the addition of one positional argument: mode

Parameters:mode (str) – Must be “start”, “stop”, “restart” or “status”
delete_pid()

Deletes the pid file, if it exists

handle(*args, **options)

The main handler. Initiates CarrotService, then handles it based on the options supplied

Parameters:options – handled by argparse
pid

Opens and reads the file stored at self.pidfile, and returns the content as an integer. If the pidfile doesn’t exist, then None is returned.

Return type:int
start(**options)

Starts the carrot service as a subprocess and records the pid

stop(hard_stop=False)

Attempts to stop the process. Performs the following actions:

  1. Asserts that the pidfile exists, or raises a MissingPid exception
  2. Runs :function:`os.kill` on a loop until an OSError is raised.
  3. Deletes the pidfile once the process if no longer running

If hard_stop is used, the process will not wait for the consumers to finish running their current tasks

Parameters:hard_stop (bool) – if True, sends a sigkill instead of a sigterm to the consumers
write_pid(pid)

Writes the pid to the pidfile

exception carrot.management.commands.carrot_daemon.MissingPid
exception carrot.management.commands.carrot_daemon.PidExists
class carrot.management.commands.carrot.Command(stdout=None, stderr=None, nocolor=False)

The main process for creating and running carrot.consumer.ConsumerSet objects and starting thes scheduler

add_arguments(parser)

Entry point for subclassed commands to add custom arguments.

handle(**options)

The actual handler process. Performs the following actions:

  • Initiates and starts a new carrot.objects.ScheduledTaskManager, which schedules all active

carrot.objects.ScheduledTask instances to run at the given intervals. This only happens if the –no-scheduler argument has not been provided - otherwise, the service only creates consumer objects

  • Loops through the queues registered in your Django project’s settings module, and starts a

new carrot.objects.ConsumerSet for them. Each ConsumerSet will contain n carrot.objects.Consumer objects, where n is the concurrency setting for the given queue (as defined in the Django settings)

  • Enters into an infinite loop which monitors your database for changes to your database - if any changes

to the carrot.objects.ScheduledTask queryset are detected, carrot updates the scheduler accordingly

On receiving a KeyboardInterrupt, SystemExit or SIGTERM, the service first turns off each of the schedulers in turn (so no new tasks can be published to RabbitMQ), before turning off the Consumers in turn. The more Consumers/ScheduledTask objects you have, the longer this will take.

Parameters:options – provided by argparse (see above for the full list of available options)