dgapplock


Namedgapplock JSON
Version 1.0.0a1 PyPI version JSON
download
home_pageNone
SummaryAppLocker
upload_time2025-07-17 11:26:14
maintainerNone
docs_urlNone
authorr.rasputin
requires_python>=3.10
licenseMIT
keywords sqlalchemy client postgresql mssql oracle
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # AppLocker - Distributed Application Lock Manager

![Python Version](https://img.shields.io/badge/python-3.8%2B-blue)
![Redis Required](https://img.shields.io/badge/requires-Redis-red)

## Overview

AppLocker is a Python library that provides distributed application locking using Redis. It ensures that only one instance of your application can run a critical section of code at a time, even across multiple servers.

Key features:
- **Distributed locking** across multiple application instances
- **Automatic lock renewal** (heartbeat) to prevent premature expiration
- **Lock ownership verification** to prevent accidental release
- **Context manager support** for easy use in `with` statements
- **Stale lock detection** and recovery

## Installation

```bash
pip install your-package-name
```

## Prerequisites

- Python 3.8+
- Redis server
- `dglog` and `dgredis` packages (will be installed automatically if using pip)

## Quick Start

```python
from app_locker import AppLocker

# Configure Redis connection
redis_config = {
    "host": "localhost",
    "port": 6379,
    # Add other Redis parameters as needed
}

# Create a locker instance
locker = AppLocker(redis_config, "my_application")

# Usage example
with locker:
    print("This code is protected by a distributed lock")
    # Only one instance of your application can execute this at a time
```

## Configuration

### Basic Configuration

When creating an `AppLocker` instance, you need to provide:

1. Redis configuration dictionary (host, port, etc.)
2. Your application name (used as part of the lock key)
3. Optional parameters:
   - `ttl`: Lock time-to-live in seconds (default: 60)
   - `logger_`: Custom logger instance

### Advanced Configuration

You can customize the lock behavior by:

1. Setting a specific lock key instead of the default `QUEUE:{application}`
2. Adjusting the stale timeout for force-release operations
3. Providing a custom logger for tracking lock operations

## Usage Examples

### Basic Locking

```python
if locker.acquire():
    try:
        # Critical section
        print("Doing important work")
    finally:
        locker.release()
else:
    print("Could not acquire lock - another instance is running")
```

### Context Manager

```python
with locker.acquired():
    # Critical section
    print("This code is protected")
```

### Checking Lock Status

```python
if locker.is_my_lock():
    print("We currently hold the lock")
    
lock_info = locker.get_lock_info()
if lock_info:
    print(f"Lock held by {lock_info['owner']} since {lock_info['acquired_at']}")
```

### Force Release Stale Lock

```python
if locker.force_release_if_stale(stale_timeout=120):
    print("Released a stale lock")
```

## Best Practices

1. **Keep TTL reasonable** - Set it long enough for your operations but not too long (default 60s is good for most cases)
2. **Always use context managers** when possible for safer lock handling
3. **Check lock ownership** before performing sensitive operations
4. **Monitor lock duration** using `get_lock_duration()` to optimize your TTL
5. **Handle lock acquisition failures** gracefully in your application

## Troubleshooting

### Common Issues

1. **Can't acquire lock**
   - Check if another instance is running
   - Verify Redis connection
   - Check if a stale lock needs to be force-released

2. **Unexpected lock release**
   - Ensure your operations complete within the TTL
   - Check for network issues with Redis

3. **Permission errors**
   - Verify Redis credentials in your configuration

### Logging

AppLocker provides detailed logging about lock operations. If you're not seeing logs:
- Make sure logging is configured properly
- Pass a custom logger to the constructor if needed

## API Reference

See the full [API documentation](API.md) for detailed information about all available methods and parameters.

## License

[MIT License](LICENSE)

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "dgapplock",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "sqlalchemy, client, postgresql, mssql, oracle",
    "author": "r.rasputin",
    "author_email": "r.rasputin@s7.ru",
    "download_url": "https://files.pythonhosted.org/packages/b6/fe/cc69695d8ac4b8801b881fbf054f4da2dce0b6d38ecfc0f6cee901313f28/dgapplock-1.0.0a1.tar.gz",
    "platform": null,
    "description": "# AppLocker - Distributed Application Lock Manager\n\n![Python Version](https://img.shields.io/badge/python-3.8%2B-blue)\n![Redis Required](https://img.shields.io/badge/requires-Redis-red)\n\n## Overview\n\nAppLocker is a Python library that provides distributed application locking using Redis. It ensures that only one instance of your application can run a critical section of code at a time, even across multiple servers.\n\nKey features:\n- **Distributed locking** across multiple application instances\n- **Automatic lock renewal** (heartbeat) to prevent premature expiration\n- **Lock ownership verification** to prevent accidental release\n- **Context manager support** for easy use in `with` statements\n- **Stale lock detection** and recovery\n\n## Installation\n\n```bash\npip install your-package-name\n```\n\n## Prerequisites\n\n- Python 3.8+\n- Redis server\n- `dglog` and `dgredis` packages (will be installed automatically if using pip)\n\n## Quick Start\n\n```python\nfrom app_locker import AppLocker\n\n# Configure Redis connection\nredis_config = {\n    \"host\": \"localhost\",\n    \"port\": 6379,\n    # Add other Redis parameters as needed\n}\n\n# Create a locker instance\nlocker = AppLocker(redis_config, \"my_application\")\n\n# Usage example\nwith locker:\n    print(\"This code is protected by a distributed lock\")\n    # Only one instance of your application can execute this at a time\n```\n\n## Configuration\n\n### Basic Configuration\n\nWhen creating an `AppLocker` instance, you need to provide:\n\n1. Redis configuration dictionary (host, port, etc.)\n2. Your application name (used as part of the lock key)\n3. Optional parameters:\n   - `ttl`: Lock time-to-live in seconds (default: 60)\n   - `logger_`: Custom logger instance\n\n### Advanced Configuration\n\nYou can customize the lock behavior by:\n\n1. Setting a specific lock key instead of the default `QUEUE:{application}`\n2. Adjusting the stale timeout for force-release operations\n3. Providing a custom logger for tracking lock operations\n\n## Usage Examples\n\n### Basic Locking\n\n```python\nif locker.acquire():\n    try:\n        # Critical section\n        print(\"Doing important work\")\n    finally:\n        locker.release()\nelse:\n    print(\"Could not acquire lock - another instance is running\")\n```\n\n### Context Manager\n\n```python\nwith locker.acquired():\n    # Critical section\n    print(\"This code is protected\")\n```\n\n### Checking Lock Status\n\n```python\nif locker.is_my_lock():\n    print(\"We currently hold the lock\")\n    \nlock_info = locker.get_lock_info()\nif lock_info:\n    print(f\"Lock held by {lock_info['owner']} since {lock_info['acquired_at']}\")\n```\n\n### Force Release Stale Lock\n\n```python\nif locker.force_release_if_stale(stale_timeout=120):\n    print(\"Released a stale lock\")\n```\n\n## Best Practices\n\n1. **Keep TTL reasonable** - Set it long enough for your operations but not too long (default 60s is good for most cases)\n2. **Always use context managers** when possible for safer lock handling\n3. **Check lock ownership** before performing sensitive operations\n4. **Monitor lock duration** using `get_lock_duration()` to optimize your TTL\n5. **Handle lock acquisition failures** gracefully in your application\n\n## Troubleshooting\n\n### Common Issues\n\n1. **Can't acquire lock**\n   - Check if another instance is running\n   - Verify Redis connection\n   - Check if a stale lock needs to be force-released\n\n2. **Unexpected lock release**\n   - Ensure your operations complete within the TTL\n   - Check for network issues with Redis\n\n3. **Permission errors**\n   - Verify Redis credentials in your configuration\n\n### Logging\n\nAppLocker provides detailed logging about lock operations. If you're not seeing logs:\n- Make sure logging is configured properly\n- Pass a custom logger to the constructor if needed\n\n## API Reference\n\nSee the full [API documentation](API.md) for detailed information about all available methods and parameters.\n\n## License\n\n[MIT License](LICENSE)\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "AppLocker",
    "version": "1.0.0a1",
    "project_urls": null,
    "split_keywords": [
        "sqlalchemy",
        " client",
        " postgresql",
        " mssql",
        " oracle"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "79c09b7bb80df4673106798363689fa006755389dbb665e1669943a80097d7a4",
                "md5": "0e76b14ea25aa5430b922d564b98e65c",
                "sha256": "176732996c28d036b70d41551e41566b8ba4fc9e084e8f4ceacd07e4896422c6"
            },
            "downloads": -1,
            "filename": "dgapplock-1.0.0a1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0e76b14ea25aa5430b922d564b98e65c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 6157,
            "upload_time": "2025-07-17T11:26:12",
            "upload_time_iso_8601": "2025-07-17T11:26:12.547051Z",
            "url": "https://files.pythonhosted.org/packages/79/c0/9b7bb80df4673106798363689fa006755389dbb665e1669943a80097d7a4/dgapplock-1.0.0a1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b6fecc69695d8ac4b8801b881fbf054f4da2dce0b6d38ecfc0f6cee901313f28",
                "md5": "f5d78835de7f55df0ae87b446e774d53",
                "sha256": "802033ab7202160ceec1fd314c7c54c57f536dc1a7f5ada1878a6526f1ca889d"
            },
            "downloads": -1,
            "filename": "dgapplock-1.0.0a1.tar.gz",
            "has_sig": false,
            "md5_digest": "f5d78835de7f55df0ae87b446e774d53",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 5623,
            "upload_time": "2025-07-17T11:26:14",
            "upload_time_iso_8601": "2025-07-17T11:26:14.024329Z",
            "url": "https://files.pythonhosted.org/packages/b6/fe/cc69695d8ac4b8801b881fbf054f4da2dce0b6d38ecfc0f6cee901313f28/dgapplock-1.0.0a1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-17 11:26:14",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "dgapplock"
}
        
Elapsed time: 1.85277s