django-marathon


Namedjango-marathon JSON
Version 0.1 PyPI version JSON
download
home_pagehttps://github.com/lazybird/django-marathon/
SummaryHelps manage single runner tasks that need to avoid concurrency issues.
upload_time2024-11-18 18:39:26
maintainerNone
docs_urlNone
authorNone
requires_pythonNone
licenseNone
keywords django single runner tasks concurrency concurrency-avoidance
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            Django Marathon
===============

Django Marathon helps manage single runner tasks that need to avoid concurrency issues,
ensuring that tasks are executed without overlapping.

Requirements
------------

- Python 3.6+
- Django 3.1+

Installation
------------

You can install Django Marathon via pip:

::

    pip install django-marathon


Add `marathon` to your Django project's `INSTALLED_APPS`:

::

    INSTALLED_APPS = [
        ...
        'marathon',
    ]


Features
--------

- Ensures single execution of tasks to avoid concurrency.
- Easy integration with Django management commands.

How Django Marathon Works
-------------------------

Under the hood, Django Marathon uses a simple locking mechanism to prevent concurrent
execution of tasks.

1. **Lock Model**: Single runner tasks will create a lock in the database,
using the `Lock` model. A lock has unique name representing the tasks.
It also has a timestamp indicating when the lock was created.
Each task that needs to avoid concurrency will first have to check the lock
table before running.

2. **SingleRunnerCommand**: This is a helper class that is designed to be used in
Django management commands.

3. **Lock Acquisition and Release**: When a command using `SingleRunnerCommand` is executed,
it first checks if a lock with the specified name exists. If it does, the command does not run.
If no lock exists, the command proceeds, and a lock is created.
Once the command completes, the lock is released, allowing future executions.


Usage With Django Management Commands
-------------------------------------

Define a tasks that should be run without concurrency.


`SingleRunnerCommand` is a base command class provided by Django Marathon to
ensure that a management command does not run concurrently.

::

    from marathon.commands import SingleRunnerCommand
    from django.core.management.base import BaseCommand

    class Command(SingleRunnerCommand, BaseCommand):
        help = 'Your command description here'

        def handle(self, *args, **options):
            self.stdout.write('Starting task...')
            # Your task logic here
            self.stdout.write('Task completed.')


Using the Locking Mechanism Outside Management Commands
-------------------------------------------------------

Django Marathon's locking mechanism can also be utilized outside of management commands.




Here's a general approach:
- Check if the lock exists
- Create a new lock if not
- Implement you task logic
- Release the lock

In practice, we would typically do the first 2 steps together.

Example Implementation:

::

    from marathon.models import Lock

    def my_task():
        lock_name = "my-unique-task-lock"
        # Get the existing lock or create a new one
        lock, created = Lock.objects.get_or_create(name=lock_name)
        if not created:
            print("Task is already running, please try again later.")
            return
        try:
            # Your task logic here
            print("Task is running...")
        except Exception as e:
            print(f"An error occurred: {str(e)}")
        finally:
            # Release the lock
            lock.delete()
        print("Task completed successfully.")

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/lazybird/django-marathon/",
    "name": "django-marathon",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "Django single runner tasks concurrency concurrency-avoidance",
    "author": null,
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/c1/7c/f72bff0a1c18b77b4ba48bb3b8fdefb1249249e516c28f3fc5b56ce2926c/django_marathon-0.1.tar.gz",
    "platform": null,
    "description": "Django Marathon\n===============\n\nDjango Marathon helps manage single runner tasks that need to avoid concurrency issues,\nensuring that tasks are executed without overlapping.\n\nRequirements\n------------\n\n- Python 3.6+\n- Django 3.1+\n\nInstallation\n------------\n\nYou can install Django Marathon via pip:\n\n::\n\n    pip install django-marathon\n\n\nAdd `marathon` to your Django project's `INSTALLED_APPS`:\n\n::\n\n    INSTALLED_APPS = [\n        ...\n        'marathon',\n    ]\n\n\nFeatures\n--------\n\n- Ensures single execution of tasks to avoid concurrency.\n- Easy integration with Django management commands.\n\nHow Django Marathon Works\n-------------------------\n\nUnder the hood, Django Marathon uses a simple locking mechanism to prevent concurrent\nexecution of tasks.\n\n1. **Lock Model**: Single runner tasks will create a lock in the database,\nusing the `Lock` model. A lock has unique name representing the tasks.\nIt also has a timestamp indicating when the lock was created.\nEach task that needs to avoid concurrency will first have to check the lock\ntable before running.\n\n2. **SingleRunnerCommand**: This is a helper class that is designed to be used in\nDjango management commands.\n\n3. **Lock Acquisition and Release**: When a command using `SingleRunnerCommand` is executed,\nit first checks if a lock with the specified name exists. If it does, the command does not run.\nIf no lock exists, the command proceeds, and a lock is created.\nOnce the command completes, the lock is released, allowing future executions.\n\n\nUsage With Django Management Commands\n-------------------------------------\n\nDefine a tasks that should be run without concurrency.\n\n\n`SingleRunnerCommand` is a base command class provided by Django Marathon to\nensure that a management command does not run concurrently.\n\n::\n\n    from marathon.commands import SingleRunnerCommand\n    from django.core.management.base import BaseCommand\n\n    class Command(SingleRunnerCommand, BaseCommand):\n        help = 'Your command description here'\n\n        def handle(self, *args, **options):\n            self.stdout.write('Starting task...')\n            # Your task logic here\n            self.stdout.write('Task completed.')\n\n\nUsing the Locking Mechanism Outside Management Commands\n-------------------------------------------------------\n\nDjango Marathon's locking mechanism can also be utilized outside of management commands.\n\n\n\n\nHere's a general approach:\n- Check if the lock exists\n- Create a new lock if not\n- Implement you task logic\n- Release the lock\n\nIn practice, we would typically do the first 2 steps together.\n\nExample Implementation:\n\n::\n\n    from marathon.models import Lock\n\n    def my_task():\n        lock_name = \"my-unique-task-lock\"\n        # Get the existing lock or create a new one\n        lock, created = Lock.objects.get_or_create(name=lock_name)\n        if not created:\n            print(\"Task is already running, please try again later.\")\n            return\n        try:\n            # Your task logic here\n            print(\"Task is running...\")\n        except Exception as e:\n            print(f\"An error occurred: {str(e)}\")\n        finally:\n            # Release the lock\n            lock.delete()\n        print(\"Task completed successfully.\")\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Helps manage single runner tasks that need to avoid concurrency issues.",
    "version": "0.1",
    "project_urls": {
        "Homepage": "https://github.com/lazybird/django-marathon/"
    },
    "split_keywords": [
        "django",
        "single",
        "runner",
        "tasks",
        "concurrency",
        "concurrency-avoidance"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c9cec3083b84472906429dec1cb4a9cbbc749aa61083a11e46cd4d8a126bf7d8",
                "md5": "ceebba3fb2cc800796d20bfbe9018a66",
                "sha256": "2069b9726ee7b7f6cd0643ca0e8bdbea5fb79c4ec5a3167c19225ce14acb5625"
            },
            "downloads": -1,
            "filename": "django_marathon-0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "ceebba3fb2cc800796d20bfbe9018a66",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 13234,
            "upload_time": "2024-11-18T18:39:24",
            "upload_time_iso_8601": "2024-11-18T18:39:24.783545Z",
            "url": "https://files.pythonhosted.org/packages/c9/ce/c3083b84472906429dec1cb4a9cbbc749aa61083a11e46cd4d8a126bf7d8/django_marathon-0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c17cf72bff0a1c18b77b4ba48bb3b8fdefb1249249e516c28f3fc5b56ce2926c",
                "md5": "5aed0f84757159edee176ddc663d3e04",
                "sha256": "a9267ba6c18c86f606b210bd66b680499993b11c4ef853e1ed29433ed3ba4fc8"
            },
            "downloads": -1,
            "filename": "django_marathon-0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "5aed0f84757159edee176ddc663d3e04",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 7669,
            "upload_time": "2024-11-18T18:39:26",
            "upload_time_iso_8601": "2024-11-18T18:39:26.104069Z",
            "url": "https://files.pythonhosted.org/packages/c1/7c/f72bff0a1c18b77b4ba48bb3b8fdefb1249249e516c28f3fc5b56ce2926c/django_marathon-0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-18 18:39:26",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "lazybird",
    "github_project": "django-marathon",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "django-marathon"
}
        
Elapsed time: 3.77788s