dsw-command-queue 4.9.4__tar.gz → 4.9.5__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dsw-command-queue
3
- Version: 4.9.4
3
+ Version: 4.9.5
4
4
  Summary: Library for working with command queue and persistent commands
5
5
  Author-email: Marek Suchánek <marek.suchanek@ds-wizard.org>
6
6
  License: Apache License 2.0
@@ -19,7 +19,8 @@ Classifier: Topic :: Utilities
19
19
  Requires-Python: <4,>=3.10
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
- Requires-Dist: dsw-database==4.9.4
22
+ Requires-Dist: func-timeout
23
+ Requires-Dist: dsw-database==4.9.5
23
24
 
24
25
  # Data Stewardship Wizard: Command Queue
25
26
 
@@ -9,9 +9,9 @@ BuildInfo = namedtuple(
9
9
  )
10
10
 
11
11
  BUILD_INFO = BuildInfo(
12
- version='v4.9.4~b3defbc',
13
- built_at='2024-09-09 12:10:23Z',
14
- sha='b3defbc09e94a677dc1d3a60834bfb04950d215f',
12
+ version='v4.9.5~d9d46ef',
13
+ built_at='2024-09-13 10:11:04Z',
14
+ sha='d9d46eff9e341643f8e594f5e6d1347a3a91f840',
15
15
  branch='HEAD',
16
- tag='v4.9.4',
16
+ tag='v4.9.5',
17
17
  )
@@ -1,5 +1,6 @@
1
1
  import abc
2
2
  import datetime
3
+ import func_timeout
3
4
  import logging
4
5
  import os
5
6
  import platform
@@ -45,21 +46,26 @@ class CommandWorker:
45
46
  def work(self, payload: PersistentCommand):
46
47
  pass
47
48
 
48
- def process_exception(self, e: Exception):
49
+ def process_timeout(self, e: BaseException):
50
+ pass
51
+
52
+ def process_exception(self, e: BaseException):
49
53
  pass
50
54
 
51
55
 
52
56
  class CommandQueue:
53
57
 
54
58
  def __init__(self, worker: CommandWorker, db: Database,
55
- channel: str, component: str, timeout: float):
59
+ channel: str, component: str, wait_timeout: float,
60
+ work_timeout: int | None = None):
56
61
  self.worker = worker
57
62
  self.db = db
58
63
  self.queries = CommandQueries(
59
64
  channel=channel,
60
65
  component=component
61
66
  )
62
- self.timeout = timeout
67
+ self.wait_timeout = wait_timeout
68
+ self.work_timeout = work_timeout
63
69
 
64
70
  @tenacity.retry(
65
71
  reraise=True,
@@ -84,7 +90,7 @@ class CommandQueue:
84
90
  self._fetch_and_process_queued()
85
91
 
86
92
  LOG.debug('Waiting for notifications')
87
- w = select.select(fds, [], [], self.timeout)
93
+ w = select.select(fds, [], [], self.wait_timeout)
88
94
 
89
95
  if INTERRUPTED:
90
96
  LOG.debug('Interrupt signal received, ending...')
@@ -92,7 +98,7 @@ class CommandQueue:
92
98
 
93
99
  if w == ([], [], []):
94
100
  LOG.debug(f'Nothing received in this cycle '
95
- f'(timeouted after {self.timeout} seconds)')
101
+ f'(timeouted after {self.wait_timeout} seconds)')
96
102
  else:
97
103
  notifications = 0
98
104
  for n in psycopg.generators.notifies(queue_conn.connection.pgconn):
@@ -141,13 +147,46 @@ class CommandQueue:
141
147
  LOG.debug(f'Previous state: {command.state}')
142
148
  LOG.debug(f'Attempts: {command.attempts} / {command.max_attempts}')
143
149
  LOG.debug(f'Last error: {command.last_error_message}')
150
+ attempt_number = command.attempts + 1
144
151
 
145
152
  try:
146
- self.worker.work(command)
153
+ self.db.execute_query(
154
+ query=self.queries.query_command_start(),
155
+ attempts=attempt_number,
156
+ updated_at=datetime.datetime.now(tz=datetime.UTC),
157
+ uuid=command.uuid,
158
+ )
159
+ self.db.conn_query.connection.commit()
160
+
161
+ def work():
162
+ self.worker.work(command)
163
+
164
+ if self.work_timeout is None:
165
+ LOG.info('Processing (without any timeout set)')
166
+ work()
167
+ else:
168
+ LOG.info(f'Processing (with timeout set to {self.work_timeout} seconds)')
169
+ func_timeout.func_timeout(
170
+ timeout=self.work_timeout,
171
+ func=work,
172
+ args=(),
173
+ kwargs=None,
174
+ )
147
175
 
148
176
  self.db.execute_query(
149
177
  query=self.queries.query_command_done(),
150
- attempts=command.attempts + 1,
178
+ attempts=attempt_number,
179
+ updated_at=datetime.datetime.now(tz=datetime.UTC),
180
+ uuid=command.uuid,
181
+ )
182
+ except func_timeout.exceptions.FunctionTimedOut as e:
183
+ msg = f'Processing exceeded time limit ({self.work_timeout} seconds)'
184
+ LOG.warning(msg)
185
+ self.worker.process_timeout(e)
186
+ self.db.execute_query(
187
+ query=self.queries.query_command_error(),
188
+ attempts=attempt_number,
189
+ error_message=msg,
151
190
  updated_at=datetime.datetime.now(tz=datetime.UTC),
152
191
  uuid=command.uuid,
153
192
  )
@@ -157,7 +196,7 @@ class CommandQueue:
157
196
  self.worker.process_exception(e)
158
197
  self.db.execute_query(
159
198
  query=self.queries.query_command_error(),
160
- attempts=command.attempts + 1,
199
+ attempts=attempt_number,
161
200
  error_message=msg,
162
201
  updated_at=datetime.datetime.now(tz=datetime.UTC),
163
202
  uuid=command.uuid,
@@ -47,3 +47,12 @@ class CommandQueries:
47
47
  updated_at = %(updated_at)s
48
48
  WHERE uuid = %(uuid)s;
49
49
  """
50
+
51
+ @staticmethod
52
+ def query_command_start() -> str:
53
+ return """
54
+ UPDATE persistent_command
55
+ SET attempts = %(attempts)s,
56
+ updated_at = %(updated_at)s
57
+ WHERE uuid = %(uuid)s;
58
+ """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dsw-command-queue
3
- Version: 4.9.4
3
+ Version: 4.9.5
4
4
  Summary: Library for working with command queue and persistent commands
5
5
  Author-email: Marek Suchánek <marek.suchanek@ds-wizard.org>
6
6
  License: Apache License 2.0
@@ -19,7 +19,8 @@ Classifier: Topic :: Utilities
19
19
  Requires-Python: <4,>=3.10
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
- Requires-Dist: dsw-database==4.9.4
22
+ Requires-Dist: func-timeout
23
+ Requires-Dist: dsw-database==4.9.5
23
24
 
24
25
  # Data Stewardship Wizard: Command Queue
25
26
 
@@ -0,0 +1,2 @@
1
+ func-timeout
2
+ dsw-database==4.9.5
@@ -4,7 +4,7 @@ build-backend = 'setuptools.build_meta'
4
4
 
5
5
  [project]
6
6
  name = 'dsw-command-queue'
7
- version = "4.9.4"
7
+ version = "4.9.5"
8
8
  description = 'Library for working with command queue and persistent commands'
9
9
  readme = 'README.md'
10
10
  keywords = ['dsw', 'subscriber', 'publisher', 'database', 'queue', 'processing']
@@ -24,8 +24,9 @@ classifiers = [
24
24
  ]
25
25
  requires-python = '>=3.10, <4'
26
26
  dependencies = [
27
+ 'func-timeout',
27
28
  # DSW
28
- "dsw-database==4.9.4",
29
+ "dsw-database==4.9.5",
29
30
  ]
30
31
 
31
32
  [project.urls]
@@ -1 +0,0 @@
1
- dsw-database==4.9.4