crazy-workers 1.2.0__tar.gz → 1.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/PKG-INFO +12 -2
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/README.md +11 -1
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/core/manager/__init__.py +8 -6
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/database/storage.py +9 -2
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers.egg-info/PKG-INFO +12 -2
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/pyproject.toml +1 -1
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/LICENSE +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/__init__.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/_bootstrap.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/boot/__init__.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/boot/__main__.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/boot/base.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/boot/detect.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/boot/entry.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/boot/orchestrator.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/boot/systemd.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/boot/windows.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/cli/__init__.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/cli/commands/__init__.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/cli/commands/params.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/cli/commands/starter.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/cli/commands/status.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/cli/commands/stopper.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/cli/discovery.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/cli/main.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/cli/ui.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/core/__init__.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/core/backend.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/core/engine.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/core/manager/lister.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/core/manager/recoverer.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/core/manager/starter.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/core/manager/stopper.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/core/recovery.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/database/__init__.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/database/schema.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/testing/__init__.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/testing/backends.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers/testing/polling.py +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers.egg-info/SOURCES.txt +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers.egg-info/dependency_links.txt +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers.egg-info/entry_points.txt +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers.egg-info/requires.txt +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/crazy_workers.egg-info/top_level.txt +0 -0
- {crazy_workers-1.2.0 → crazy_workers-1.3.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crazy-workers
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: A Python library for managing background worker processes with persistent state, automatic recovery, and a CLI.
|
|
5
5
|
Author: GioVanni Colasanto
|
|
6
6
|
License: MIT
|
|
@@ -139,8 +139,9 @@ See [CLI.md](https://github.com/Vanni-broUser/crazy-workers/blob/main/CLI.md) fo
|
|
|
139
139
|
| `engine` | `Engine` | `None` | Reuse an existing SQLAlchemy engine so the tables live in your database; **not** disposed by crazy_workers |
|
|
140
140
|
| `worker_env` | `dict` | `None` | Environment variables injected into **every** spawned worker (e.g. `DATABASE_URL`) |
|
|
141
141
|
| `auto_recover` | `bool` | `True` | Recover dead-but-`RUNNING` workers when the manager is constructed |
|
|
142
|
+
| `create_tables` | `bool` | `True` | Create crazy_workers' own tables on init; set `False` when the host owns the schema via its migrations |
|
|
142
143
|
|
|
143
|
-
See [Backend integration](#backend-integration) for `db_url` / `engine` / `worker_env` / `auto_recover`.
|
|
144
|
+
See [Backend integration](#backend-integration) for `db_url` / `engine` / `worker_env` / `auto_recover` / `create_tables`.
|
|
144
145
|
|
|
145
146
|
### `start_worker(worker_type, worker_key=None, parameters=None, env=None)`
|
|
146
147
|
|
|
@@ -338,6 +339,15 @@ the project instead of living off to the side:
|
|
|
338
339
|
`workers` table inside your database and inherits its persistence and backups
|
|
339
340
|
— so state survives even if the process/container is recreated. A shared
|
|
340
341
|
engine is never disposed by crazy_workers; its owner manages it.
|
|
342
|
+
- **Let your migrations own the schema.** If your project tracks its schema with
|
|
343
|
+
a migration tool (Alembic, etc.), pass `create_tables=False` so crazy_workers
|
|
344
|
+
issues no DDL: the `workers` table becomes a normal migration in your history,
|
|
345
|
+
with a single source of truth and no create-on-import side effect. You own the
|
|
346
|
+
ordering — the table must exist before the manager queries it, so build the
|
|
347
|
+
manager *after* your migrations run (and keep `auto_recover=False` until then,
|
|
348
|
+
since recovery reads that table). See the `workers` schema in
|
|
349
|
+
[`crazy_workers/database/schema.py`](https://github.com/Vanni-broUser/crazy-workers/blob/main/crazy_workers/database/schema.py)
|
|
350
|
+
for the columns your migration must create.
|
|
341
351
|
- **Give workers the connection they need.** A worker is a separate process, so
|
|
342
352
|
it can't receive a live DB connection — pass the *configuration* instead.
|
|
343
353
|
`worker_env={'DATABASE_URL': ...}` is injected into every spawned worker
|
|
@@ -104,8 +104,9 @@ See [CLI.md](https://github.com/Vanni-broUser/crazy-workers/blob/main/CLI.md) fo
|
|
|
104
104
|
| `engine` | `Engine` | `None` | Reuse an existing SQLAlchemy engine so the tables live in your database; **not** disposed by crazy_workers |
|
|
105
105
|
| `worker_env` | `dict` | `None` | Environment variables injected into **every** spawned worker (e.g. `DATABASE_URL`) |
|
|
106
106
|
| `auto_recover` | `bool` | `True` | Recover dead-but-`RUNNING` workers when the manager is constructed |
|
|
107
|
+
| `create_tables` | `bool` | `True` | Create crazy_workers' own tables on init; set `False` when the host owns the schema via its migrations |
|
|
107
108
|
|
|
108
|
-
See [Backend integration](#backend-integration) for `db_url` / `engine` / `worker_env` / `auto_recover`.
|
|
109
|
+
See [Backend integration](#backend-integration) for `db_url` / `engine` / `worker_env` / `auto_recover` / `create_tables`.
|
|
109
110
|
|
|
110
111
|
### `start_worker(worker_type, worker_key=None, parameters=None, env=None)`
|
|
111
112
|
|
|
@@ -303,6 +304,15 @@ the project instead of living off to the side:
|
|
|
303
304
|
`workers` table inside your database and inherits its persistence and backups
|
|
304
305
|
— so state survives even if the process/container is recreated. A shared
|
|
305
306
|
engine is never disposed by crazy_workers; its owner manages it.
|
|
307
|
+
- **Let your migrations own the schema.** If your project tracks its schema with
|
|
308
|
+
a migration tool (Alembic, etc.), pass `create_tables=False` so crazy_workers
|
|
309
|
+
issues no DDL: the `workers` table becomes a normal migration in your history,
|
|
310
|
+
with a single source of truth and no create-on-import side effect. You own the
|
|
311
|
+
ordering — the table must exist before the manager queries it, so build the
|
|
312
|
+
manager *after* your migrations run (and keep `auto_recover=False` until then,
|
|
313
|
+
since recovery reads that table). See the `workers` schema in
|
|
314
|
+
[`crazy_workers/database/schema.py`](https://github.com/Vanni-broUser/crazy-workers/blob/main/crazy_workers/database/schema.py)
|
|
315
|
+
for the columns your migration must create.
|
|
306
316
|
- **Give workers the connection they need.** A worker is a separate process, so
|
|
307
317
|
it can't receive a live DB connection — pass the *configuration* instead.
|
|
308
318
|
`worker_env={'DATABASE_URL': ...}` is injected into every spawned worker
|
|
@@ -25,6 +25,7 @@ class WorkerManager:
|
|
|
25
25
|
engine=None,
|
|
26
26
|
worker_env=None,
|
|
27
27
|
auto_recover=True,
|
|
28
|
+
create_tables=True,
|
|
28
29
|
):
|
|
29
30
|
self.workers_dir = workers_dir
|
|
30
31
|
self._validate_workers_dir(create_dir)
|
|
@@ -33,7 +34,7 @@ class WorkerManager:
|
|
|
33
34
|
self.logs_dir = os.path.join(self.service_dir, 'logs')
|
|
34
35
|
self.db_path = os.path.join(self.service_dir, 'workers.db')
|
|
35
36
|
|
|
36
|
-
self._initialize_storage(create_dir, db_url, engine)
|
|
37
|
+
self._initialize_storage(create_dir, db_url, engine, create_tables)
|
|
37
38
|
# The backend is the only component that touches OS processes. The default
|
|
38
39
|
# spawns real subprocesses; tests can swap in a fake one (see for_testing).
|
|
39
40
|
self.backend = backend or SubprocessBackend()
|
|
@@ -86,7 +87,7 @@ class WorkerManager:
|
|
|
86
87
|
else:
|
|
87
88
|
raise ValueError(f'Workers directory "{self.workers_dir}" does not exist.')
|
|
88
89
|
|
|
89
|
-
def _initialize_storage(self, create_dir, db_url, engine):
|
|
90
|
+
def _initialize_storage(self, create_dir, db_url, engine, create_tables):
|
|
90
91
|
"""Sets up service directories and storage if allowed or if they already exist."""
|
|
91
92
|
if create_dir:
|
|
92
93
|
os.makedirs(self.service_dir, exist_ok=True)
|
|
@@ -94,11 +95,12 @@ class WorkerManager:
|
|
|
94
95
|
|
|
95
96
|
if engine is not None or db_url is not None:
|
|
96
97
|
# External/shared database (e.g. the host backend's). crazy_workers' tables
|
|
97
|
-
# are created there
|
|
98
|
-
# recovery lock and the
|
|
99
|
-
|
|
98
|
+
# are created there unless the host owns the schema (create_tables=False);
|
|
99
|
+
# the local .service dir is still used for logs, the recovery lock and the
|
|
100
|
+
# boot marker.
|
|
101
|
+
self.storage = Storage(db_url=db_url, engine=engine, create_tables=create_tables)
|
|
100
102
|
elif create_dir or os.path.exists(self.db_path):
|
|
101
|
-
self.storage = Storage(self.db_path)
|
|
103
|
+
self.storage = Storage(self.db_path, create_tables=create_tables)
|
|
102
104
|
else:
|
|
103
105
|
self.storage = None
|
|
104
106
|
|
|
@@ -19,9 +19,15 @@ class Storage:
|
|
|
19
19
|
A shared engine is NOT disposed by crazy_workers — its owner manages it.
|
|
20
20
|
- ``db_url``: any SQLAlchemy URL (e.g. ``postgresql://user:pass@host/db``).
|
|
21
21
|
- ``db_path``: a SQLite file path — the default, self-contained mode.
|
|
22
|
+
|
|
23
|
+
``create_tables`` controls whether crazy_workers creates its own tables on
|
|
24
|
+
init. Leave it ``True`` for the self-contained modes. Set it ``False`` when
|
|
25
|
+
the host owns the schema (e.g. it manages crazy_workers' ``workers`` table
|
|
26
|
+
through its own migrations): crazy_workers then issues no DDL, and the caller
|
|
27
|
+
is responsible for the table existing before the storage is used.
|
|
22
28
|
"""
|
|
23
29
|
|
|
24
|
-
def __init__(self, db_path=None, *, db_url=None, engine=None):
|
|
30
|
+
def __init__(self, db_path=None, *, db_url=None, engine=None, create_tables=True):
|
|
25
31
|
self.db_path = db_path
|
|
26
32
|
|
|
27
33
|
if engine is not None:
|
|
@@ -37,7 +43,8 @@ class Storage:
|
|
|
37
43
|
self._install_sqlite_tuning()
|
|
38
44
|
|
|
39
45
|
self.Session = sessionmaker(bind=self.engine)
|
|
40
|
-
|
|
46
|
+
if create_tables:
|
|
47
|
+
self._ensure_tables()
|
|
41
48
|
|
|
42
49
|
def _install_sqlite_tuning(self):
|
|
43
50
|
@event.listens_for(self.engine, 'connect')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crazy-workers
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: A Python library for managing background worker processes with persistent state, automatic recovery, and a CLI.
|
|
5
5
|
Author: GioVanni Colasanto
|
|
6
6
|
License: MIT
|
|
@@ -139,8 +139,9 @@ See [CLI.md](https://github.com/Vanni-broUser/crazy-workers/blob/main/CLI.md) fo
|
|
|
139
139
|
| `engine` | `Engine` | `None` | Reuse an existing SQLAlchemy engine so the tables live in your database; **not** disposed by crazy_workers |
|
|
140
140
|
| `worker_env` | `dict` | `None` | Environment variables injected into **every** spawned worker (e.g. `DATABASE_URL`) |
|
|
141
141
|
| `auto_recover` | `bool` | `True` | Recover dead-but-`RUNNING` workers when the manager is constructed |
|
|
142
|
+
| `create_tables` | `bool` | `True` | Create crazy_workers' own tables on init; set `False` when the host owns the schema via its migrations |
|
|
142
143
|
|
|
143
|
-
See [Backend integration](#backend-integration) for `db_url` / `engine` / `worker_env` / `auto_recover`.
|
|
144
|
+
See [Backend integration](#backend-integration) for `db_url` / `engine` / `worker_env` / `auto_recover` / `create_tables`.
|
|
144
145
|
|
|
145
146
|
### `start_worker(worker_type, worker_key=None, parameters=None, env=None)`
|
|
146
147
|
|
|
@@ -338,6 +339,15 @@ the project instead of living off to the side:
|
|
|
338
339
|
`workers` table inside your database and inherits its persistence and backups
|
|
339
340
|
— so state survives even if the process/container is recreated. A shared
|
|
340
341
|
engine is never disposed by crazy_workers; its owner manages it.
|
|
342
|
+
- **Let your migrations own the schema.** If your project tracks its schema with
|
|
343
|
+
a migration tool (Alembic, etc.), pass `create_tables=False` so crazy_workers
|
|
344
|
+
issues no DDL: the `workers` table becomes a normal migration in your history,
|
|
345
|
+
with a single source of truth and no create-on-import side effect. You own the
|
|
346
|
+
ordering — the table must exist before the manager queries it, so build the
|
|
347
|
+
manager *after* your migrations run (and keep `auto_recover=False` until then,
|
|
348
|
+
since recovery reads that table). See the `workers` schema in
|
|
349
|
+
[`crazy_workers/database/schema.py`](https://github.com/Vanni-broUser/crazy-workers/blob/main/crazy_workers/database/schema.py)
|
|
350
|
+
for the columns your migration must create.
|
|
341
351
|
- **Give workers the connection they need.** A worker is a separate process, so
|
|
342
352
|
it can't receive a live DB connection — pass the *configuration* instead.
|
|
343
353
|
`worker_env={'DATABASE_URL': ...}` is injected into every spawned worker
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "crazy-workers"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.3.0"
|
|
4
4
|
description = "A Python library for managing background worker processes with persistent state, automatic recovery, and a CLI."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "GioVanni Colasanto" }]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|