lockfolder


Namelockfolder JSON
Version 1.0.2 PyPI version JSON
download
home_pagehttps://github.com/LionKimbro/lockfolder
Summarycheck-bid-check into a lock folder, to obtain a lock
upload_time2023-12-01 23:37:45
maintainer
docs_urlNone
authorLion Kimbro
requires_python>=3.7
license
keywords mutex lock locking guid
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Lock Folder

Obtain a lock by posting a bid into a lock folder, and checking for rivals.

#### Installation

```
pip install lockfolder
```

### How to Use It


```
import pathlib
from lockfolder import lockfolder

lockfolder.init()

p = pathlib.Path("path/to/lockfolder")

if lockfolder.lock(p):
    print("aquired lock")
    ...
    ...
    lockfolder.unlock(p)
else:
    print("failed to aquire lock")
```

Adapt to context manager, throw-finally systems, decorator, what have
you, as you like.


### Lock Files

Lock files are JSON files that are logically equivalent to:

```
----------[ filename: <GUID>.json ]-----------------------------------
  {
    "PID": <integer PID>,
    "CREATED": <integer timestamp>
  }
----------------------------------------------------------------------
```


### Concept

This is a mutex system, that ensures that only one process has access to a resource.

It's defining features are:
* a filesystem folder is used to bid for a lock
* it is cross-platform to contemporary operating systems
* it's very simple
* it has only one external dependency: `psutil`
* it is robust to recycled PIDs

Some of the limitations of this system, are:
* live-locks are possible, which occurs when too many processes all try to get a lock at the same time
   * all petitioners will fail to achieve a lock
   * insistent petitioners should repeat efforts at connection with an exponential backoff
* security and file permissions are not taken account of
   * it is possible for a malicious user or process to manually delete or create lock files
* there is an extremely unlikely possibility of a v4 GUID collision
* PID recycling fails if the same PID is recycled to a competitor within the second (highly unusual) 


### Basic Strategy:

* each process self-assigns a GUID
* each process notes its PID
* each process notes its create-time
* a folder keeps the locks for the resource ("bids" and "locks" are the same thing in this system)
* the procedure is "check-bid-check", and if any check shows another bid/lock, the process deletes its own bid (if it got that far) and returns "fail"
* if the "check-bid-check" passes, then the bid is left until the process completes, at which point the bid is deleted
* bids contain the process PID and creation time of the process, and may be deleted by any process that wishes to challenge a prior bid, provided that it can determine that a process created at <create-time> with process ID <PID> is no longer running
* upon a fail, at the programmer's discretion, processes may delay and retry, with delays having a random component, and increasing duration between attempts


### Procedure:

Here is the basic procedure more specifically:

STEP 10. **CHECK** -- check the lock folder for the presence of any files; if there are files, END (error state: FAIL); if there are no files, proceed to step 20

STEP 20. **BID** -- write a file into the lock folder, containing the following, then proceed to step 30

* filename: `(self-selected-GUID-for-this-process).json`
* JSON file content:
   * PID: `(process-id)`
   * PROCESS-START-TIME: `(timestamp-for-this-process)`

STEP 30. **CHECK** -- check the lock folder for the presence of any files, other than my own: if there are other files, proceed to step 40, otherwise, proceed to step 50

STEP 40. **DELETE & FAIL** -- delete the bid file that was created in step 20, then END (error state: FAIL)

STEP 50. **OPERATE** -- the lock has been acquired (it's the same file as the bid created in step 20) -- do whatever you please with it

STEP 60. **DELETE & END** -- delete the bid file that was created in step 20, then END (error state: SUCCESS)


### Additional Resources

* https://www.reddit.com/r/AskProgramming/comments/186ot93/is_this_checkbidcheck_mutex_strategy_okay/ -- a Reddit thread, in which I requested verification of correctness for this system.

written: 2023-11-29


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/LionKimbro/lockfolder",
    "name": "lockfolder",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "mutex,lock,locking,guid",
    "author": "Lion Kimbro",
    "author_email": "Lion Kimbro <lionkimbro@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/f4/44/0295d7b85f25b59c2ecdd1740104dd40e997ebfe7481f2180e6f1dd0c1ca/lockfolder-1.0.2.tar.gz",
    "platform": null,
    "description": "# Lock Folder\r\n\r\nObtain a lock by posting a bid into a lock folder, and checking for rivals.\r\n\r\n#### Installation\r\n\r\n```\r\npip install lockfolder\r\n```\r\n\r\n### How to Use It\r\n\r\n\r\n```\r\nimport pathlib\r\nfrom lockfolder import lockfolder\r\n\r\nlockfolder.init()\r\n\r\np = pathlib.Path(\"path/to/lockfolder\")\r\n\r\nif lockfolder.lock(p):\r\n    print(\"aquired lock\")\r\n    ...\r\n    ...\r\n    lockfolder.unlock(p)\r\nelse:\r\n    print(\"failed to aquire lock\")\r\n```\r\n\r\nAdapt to context manager, throw-finally systems, decorator, what have\r\nyou, as you like.\r\n\r\n\r\n### Lock Files\r\n\r\nLock files are JSON files that are logically equivalent to:\r\n\r\n```\r\n----------[ filename: <GUID>.json ]-----------------------------------\r\n  {\r\n    \"PID\": <integer PID>,\r\n    \"CREATED\": <integer timestamp>\r\n  }\r\n----------------------------------------------------------------------\r\n```\r\n\r\n\r\n### Concept\r\n\r\nThis is a mutex system, that ensures that only one process has access to a resource.\r\n\r\nIt's defining features are:\r\n* a filesystem folder is used to bid for a lock\r\n* it is cross-platform to contemporary operating systems\r\n* it's very simple\r\n* it has only one external dependency: `psutil`\r\n* it is robust to recycled PIDs\r\n\r\nSome of the limitations of this system, are:\r\n* live-locks are possible, which occurs when too many processes all try to get a lock at the same time\r\n   * all petitioners will fail to achieve a lock\r\n   * insistent petitioners should repeat efforts at connection with an exponential backoff\r\n* security and file permissions are not taken account of\r\n   * it is possible for a malicious user or process to manually delete or create lock files\r\n* there is an extremely unlikely possibility of a v4 GUID collision\r\n* PID recycling fails if the same PID is recycled to a competitor within the second (highly unusual) \r\n\r\n\r\n### Basic Strategy:\r\n\r\n* each process self-assigns a GUID\r\n* each process notes its PID\r\n* each process notes its create-time\r\n* a folder keeps the locks for the resource (\"bids\" and \"locks\" are the same thing in this system)\r\n* the procedure is \"check-bid-check\", and if any check shows another bid/lock, the process deletes its own bid (if it got that far) and returns \"fail\"\r\n* if the \"check-bid-check\" passes, then the bid is left until the process completes, at which point the bid is deleted\r\n* bids contain the process PID and creation time of the process, and may be deleted by any process that wishes to challenge a prior bid, provided that it can determine that a process created at <create-time> with process ID <PID> is no longer running\r\n* upon a fail, at the programmer's discretion, processes may delay and retry, with delays having a random component, and increasing duration between attempts\r\n\r\n\r\n### Procedure:\r\n\r\nHere is the basic procedure more specifically:\r\n\r\nSTEP 10. **CHECK** -- check the lock folder for the presence of any files; if there are files, END (error state: FAIL); if there are no files, proceed to step 20\r\n\r\nSTEP 20. **BID** -- write a file into the lock folder, containing the following, then proceed to step 30\r\n\r\n* filename: `(self-selected-GUID-for-this-process).json`\r\n* JSON file content:\r\n   * PID: `(process-id)`\r\n   * PROCESS-START-TIME: `(timestamp-for-this-process)`\r\n\r\nSTEP 30. **CHECK** -- check the lock folder for the presence of any files, other than my own: if there are other files, proceed to step 40, otherwise, proceed to step 50\r\n\r\nSTEP 40. **DELETE & FAIL** -- delete the bid file that was created in step 20, then END (error state: FAIL)\r\n\r\nSTEP 50. **OPERATE** -- the lock has been acquired (it's the same file as the bid created in step 20) -- do whatever you please with it\r\n\r\nSTEP 60. **DELETE & END** -- delete the bid file that was created in step 20, then END (error state: SUCCESS)\r\n\r\n\r\n### Additional Resources\r\n\r\n* https://www.reddit.com/r/AskProgramming/comments/186ot93/is_this_checkbidcheck_mutex_strategy_okay/ -- a Reddit thread, in which I requested verification of correctness for this system.\r\n\r\nwritten: 2023-11-29\r\n\r\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "check-bid-check into a lock folder, to obtain a lock",
    "version": "1.0.2",
    "project_urls": {
        "Bug Tracker": "https://github.com/LionKimbro/lockfolder/issues",
        "Homepage": "https://github.com/LionKimbro/lockfolder"
    },
    "split_keywords": [
        "mutex",
        "lock",
        "locking",
        "guid"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f4440295d7b85f25b59c2ecdd1740104dd40e997ebfe7481f2180e6f1dd0c1ca",
                "md5": "df974de60df48faf653e562c41026181",
                "sha256": "a0cc6fca633503cd265a1ce67f8c0fa229c54af620a972f0ea2ac107cafa62d2"
            },
            "downloads": -1,
            "filename": "lockfolder-1.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "df974de60df48faf653e562c41026181",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 6522,
            "upload_time": "2023-12-01T23:37:45",
            "upload_time_iso_8601": "2023-12-01T23:37:45.009759Z",
            "url": "https://files.pythonhosted.org/packages/f4/44/0295d7b85f25b59c2ecdd1740104dd40e997ebfe7481f2180e6f1dd0c1ca/lockfolder-1.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-01 23:37:45",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "LionKimbro",
    "github_project": "lockfolder",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [],
    "lcname": "lockfolder"
}
        
Elapsed time: 0.16825s