beanqueue 0.2.0__tar.gz → 0.2.1__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.
- {beanqueue-0.2.0 → beanqueue-0.2.1}/PKG-INFO +2 -2
- {beanqueue-0.2.0 → beanqueue-0.2.1}/README.md +1 -1
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/app.py +71 -1
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/config.py +9 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/pyproject.toml +1 -1
- {beanqueue-0.2.0 → beanqueue-0.2.1}/LICENSE +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/__init__.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/cmds/__init__.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/cmds/create_tables.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/cmds/process.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/cmds/submit.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/cmds/utils.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/constants.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/db/__init__.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/db/base.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/db/session.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/events.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/models/__init__.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/models/helpers.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/models/task.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/models/worker.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/processors/__init__.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/processors/processor.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/processors/registry.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/services/__init__.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/services/dispatch.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/services/worker.py +0 -0
- {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: beanqueue
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: BeanQueue or BQ for short, PostgreSQL SKIP LOCK based worker queue library
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Fang-Pen Lin
|
|
@@ -151,7 +151,7 @@ config = bq.Config(
|
|
|
151
151
|
app = bq.BeanQueue(config=config)
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
-
Then you can pass `--app` argument pointing to the app object to the process command like this:
|
|
154
|
+
Then you can pass `--app` argument (or `-a` for short) pointing to the app object to the process command like this:
|
|
155
155
|
|
|
156
156
|
```bash
|
|
157
157
|
python -m bq.cmds.process -a my_pkgs.bq.app images
|
|
@@ -131,7 +131,7 @@ config = bq.Config(
|
|
|
131
131
|
app = bq.BeanQueue(config=config)
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
-
Then you can pass `--app` argument pointing to the app object to the process command like this:
|
|
134
|
+
Then you can pass `--app` argument (or `-a` for short) pointing to the app object to the process command like this:
|
|
135
135
|
|
|
136
136
|
```bash
|
|
137
137
|
python -m bq.cmds.process -a my_pkgs.bq.app images
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
import importlib
|
|
3
|
+
import json
|
|
3
4
|
import logging
|
|
4
5
|
import platform
|
|
5
6
|
import sys
|
|
6
7
|
import threading
|
|
7
8
|
import time
|
|
8
9
|
import typing
|
|
10
|
+
from wsgiref.simple_server import make_server
|
|
9
11
|
|
|
10
12
|
import venusian
|
|
11
13
|
from sqlalchemy import func
|
|
@@ -150,7 +152,9 @@ class BeanQueue:
|
|
|
150
152
|
# is set too short. It could also be the administrator update the worker state to something else than
|
|
151
153
|
# RUNNING. Regardless the reason, let's stop processing.
|
|
152
154
|
logger.warning(
|
|
153
|
-
"Current worker %s state is %s instead of running, quit processing"
|
|
155
|
+
"Current worker %s state is %s instead of running, quit processing",
|
|
156
|
+
current_worker.id,
|
|
157
|
+
current_worker.state,
|
|
154
158
|
)
|
|
155
159
|
sys.exit(0)
|
|
156
160
|
|
|
@@ -159,6 +163,61 @@ class BeanQueue:
|
|
|
159
163
|
db.add(current_worker)
|
|
160
164
|
db.commit()
|
|
161
165
|
|
|
166
|
+
def _serve_http_request(
|
|
167
|
+
self, worker_id: typing.Any, environ: dict, start_response: typing.Callable
|
|
168
|
+
) -> list[bytes]:
|
|
169
|
+
path = environ["PATH_INFO"]
|
|
170
|
+
if path == "/healthz":
|
|
171
|
+
db = self.make_session()
|
|
172
|
+
worker_service = self._make_worker_service(db)
|
|
173
|
+
worker = worker_service.get_worker(worker_id)
|
|
174
|
+
if worker is not None and worker.state == models.WorkerState.RUNNING:
|
|
175
|
+
start_response(
|
|
176
|
+
"200 OK",
|
|
177
|
+
[
|
|
178
|
+
("Content-Type", "application/json"),
|
|
179
|
+
],
|
|
180
|
+
)
|
|
181
|
+
return [
|
|
182
|
+
json.dumps(dict(status="ok", worker_id=str(worker_id))).encode(
|
|
183
|
+
"utf8"
|
|
184
|
+
)
|
|
185
|
+
]
|
|
186
|
+
else:
|
|
187
|
+
logger.warning("Bad worker %s state %s", worker_id, worker.state)
|
|
188
|
+
start_response(
|
|
189
|
+
"500 Internal Server Error",
|
|
190
|
+
[
|
|
191
|
+
("Content-Type", "application/json"),
|
|
192
|
+
],
|
|
193
|
+
)
|
|
194
|
+
return [
|
|
195
|
+
json.dumps(
|
|
196
|
+
dict(
|
|
197
|
+
status="internal error",
|
|
198
|
+
worker_id=str(worker_id),
|
|
199
|
+
state=str(worker.state),
|
|
200
|
+
)
|
|
201
|
+
).encode("utf8")
|
|
202
|
+
]
|
|
203
|
+
# TODO: add other metrics endpoints
|
|
204
|
+
start_response(
|
|
205
|
+
"404 NOT FOUND",
|
|
206
|
+
[
|
|
207
|
+
("Content-Type", "application/json"),
|
|
208
|
+
],
|
|
209
|
+
)
|
|
210
|
+
return [json.dumps(dict(status="not found")).encode("utf8")]
|
|
211
|
+
|
|
212
|
+
def run_metrics_http_server(self, worker_id: typing.Any):
|
|
213
|
+
host = self.config.METRICS_HTTP_SERVER_INTERFACE
|
|
214
|
+
port = self.config.METRICS_HTTP_SERVER_PORT
|
|
215
|
+
with make_server(
|
|
216
|
+
host, port, functools.partial(self._serve_http_request, worker_id)
|
|
217
|
+
) as httpd:
|
|
218
|
+
logger.info("Run metrics HTTP server on %s:%s", host, port)
|
|
219
|
+
httpd.serve_forever()
|
|
220
|
+
|
|
162
221
|
def process_tasks(
|
|
163
222
|
self,
|
|
164
223
|
channels: tuple[str, ...],
|
|
@@ -194,6 +253,15 @@ class BeanQueue:
|
|
|
194
253
|
dispatch_service.listen(channels)
|
|
195
254
|
db.commit()
|
|
196
255
|
|
|
256
|
+
metrics_server_thread = None
|
|
257
|
+
if self.config.METRICS_HTTP_SERVER_ENABLED:
|
|
258
|
+
metrics_server_thread = threading.Thread(
|
|
259
|
+
target=self.run_metrics_http_server,
|
|
260
|
+
args=(worker.id,),
|
|
261
|
+
)
|
|
262
|
+
metrics_server_thread.daemon = True
|
|
263
|
+
metrics_server_thread.start()
|
|
264
|
+
|
|
197
265
|
logger.info("Created worker %s, name=%s", worker.id, worker.name)
|
|
198
266
|
events.worker_init.send(self, worker=worker)
|
|
199
267
|
|
|
@@ -249,6 +317,8 @@ class BeanQueue:
|
|
|
249
317
|
db.rollback()
|
|
250
318
|
logger.info("Shutting down ...")
|
|
251
319
|
worker_update_thread.join(5)
|
|
320
|
+
if metrics_server_thread is not None:
|
|
321
|
+
metrics_server_thread.join(5)
|
|
252
322
|
|
|
253
323
|
worker.state = models.WorkerState.SHUTDOWN
|
|
254
324
|
db.add(worker)
|
|
@@ -30,6 +30,15 @@ class Config(BaseSettings):
|
|
|
30
30
|
# which worker model to use
|
|
31
31
|
WORKER_MODEL: str = "bq.Worker"
|
|
32
32
|
|
|
33
|
+
# Enable metrics HTTP server
|
|
34
|
+
METRICS_HTTP_SERVER_ENABLED: bool = True
|
|
35
|
+
|
|
36
|
+
# the metrics http server interface to listen
|
|
37
|
+
METRICS_HTTP_SERVER_INTERFACE: str = ""
|
|
38
|
+
|
|
39
|
+
# the metrics http server port to listen
|
|
40
|
+
METRICS_HTTP_SERVER_PORT: int = 8000
|
|
41
|
+
|
|
33
42
|
POSTGRES_SERVER: str = "localhost"
|
|
34
43
|
POSTGRES_USER: str = "bq"
|
|
35
44
|
POSTGRES_PASSWORD: str = ""
|
|
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
|