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.
Files changed (28) hide show
  1. {beanqueue-0.2.0 → beanqueue-0.2.1}/PKG-INFO +2 -2
  2. {beanqueue-0.2.0 → beanqueue-0.2.1}/README.md +1 -1
  3. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/app.py +71 -1
  4. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/config.py +9 -0
  5. {beanqueue-0.2.0 → beanqueue-0.2.1}/pyproject.toml +1 -1
  6. {beanqueue-0.2.0 → beanqueue-0.2.1}/LICENSE +0 -0
  7. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/__init__.py +0 -0
  8. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/cmds/__init__.py +0 -0
  9. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/cmds/create_tables.py +0 -0
  10. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/cmds/process.py +0 -0
  11. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/cmds/submit.py +0 -0
  12. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/cmds/utils.py +0 -0
  13. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/constants.py +0 -0
  14. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/db/__init__.py +0 -0
  15. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/db/base.py +0 -0
  16. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/db/session.py +0 -0
  17. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/events.py +0 -0
  18. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/models/__init__.py +0 -0
  19. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/models/helpers.py +0 -0
  20. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/models/task.py +0 -0
  21. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/models/worker.py +0 -0
  22. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/processors/__init__.py +0 -0
  23. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/processors/processor.py +0 -0
  24. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/processors/registry.py +0 -0
  25. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/services/__init__.py +0 -0
  26. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/services/dispatch.py +0 -0
  27. {beanqueue-0.2.0 → beanqueue-0.2.1}/bq/services/worker.py +0 -0
  28. {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.0
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 = ""
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "beanqueue"
3
- version = "0.2.0"
3
+ version = "0.2.1"
4
4
  description = "BeanQueue or BQ for short, PostgreSQL SKIP LOCK based worker queue library"
5
5
  authors = ["Fang-Pen Lin <fangpen@launchplatform.com>"]
6
6
  license = "MIT"
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