libpipe 0.2__tar.gz → 0.4__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: libpipe
3
- Version: 0.2
3
+ Version: 0.4
4
4
  Summary:
5
5
  Home-page: https://gitlab.com/flomertens/libpipe
6
6
  License: GPL-3.0-or-later
@@ -1,6 +1,7 @@
1
1
  import os
2
2
  import string
3
3
  import random
4
+ import functools
4
5
 
5
6
  from unittest import mock
6
7
 
@@ -173,6 +174,37 @@ def test_done_callback():
173
174
  assert done
174
175
 
175
176
 
177
+ def test_task_done_callback():
178
+ w = worker.WorkerPool([worker.localhost_shortname], 'Test', max_time=2)
179
+
180
+ done = 0
181
+
182
+ def callback(task):
183
+ print(task)
184
+ nonlocal done
185
+ assert isinstance(task, worker.Task)
186
+ if task.name == 'Error':
187
+ assert task.returncode == 1
188
+ else:
189
+ assert task.returncode == 0
190
+ done += 1
191
+
192
+ def callback_with_extra(name, task):
193
+ assert name == 'test'
194
+ callback(task)
195
+
196
+ w.add('echo 0', task_done_callback=callback, name='Success1')
197
+ w.add('echo 0', task_done_callback=callback, name='Success2')
198
+ w.add('echo 3; cat non_existing_file', task_done_callback=functools.partial(callback_with_extra, 'test'), name='Error')
199
+ w.add('echo 4;', task_done_callback=functools.partial(callback_with_extra, 'test_err'), name='CBK Error')
200
+
201
+ success, errors = w.execute()
202
+
203
+ assert len(success) == 4
204
+ assert len(errors) == 0
205
+ assert done == 3
206
+
207
+
176
208
  class FakeSSHClient(worker.LocalClient):
177
209
 
178
210
  def __init__(self, host, user=None, force_sync=True, password=None):
@@ -229,3 +261,9 @@ def test_line_too_long(tmp_path):
229
261
  assert has_done
230
262
  assert len(errors) == 0
231
263
  assert len(success) == 3
264
+
265
+
266
+ def test_client():
267
+ client = worker.Client('localhost')
268
+
269
+ task = worker.Task('Check size', 'du -hs *')
@@ -91,7 +91,7 @@ class Task(object):
91
91
  returncode (int): Return code. None if task was not executed.
92
92
  """
93
93
 
94
- def __init__(self, name, command, output_file=None, done_callback=None,
94
+ def __init__(self, name, command, output_file=None, done_callback=None, task_done_callback=None,
95
95
  run_on_host=None, n_try=3, pid_filename=None, keep_pid_file_on_error=False):
96
96
  self.name = name
97
97
  self.command = command
@@ -99,7 +99,8 @@ class Task(object):
99
99
  self.fd = None
100
100
  self.returncode = None
101
101
  self.n_try = 0
102
- self.done_callback = done_callback
102
+ self._done_callback = done_callback
103
+ self._task_done_callback = task_done_callback
103
104
  self.run_on_host = run_on_host
104
105
  self.status = TaskStatus.WAITING
105
106
  self.process = None
@@ -108,6 +109,21 @@ class Task(object):
108
109
  self.pid_filename = pid_filename
109
110
  self.keep_pid_file_on_error = keep_pid_file_on_error
110
111
 
112
+ def done_callback(self):
113
+ err_msg = ''
114
+ if self._done_callback is not None:
115
+ try:
116
+ self._done_callback()
117
+ except Exception as exc:
118
+ err_msg = f'Error executing return callback of task {self.name}: {str(exc)}\n'
119
+ if self._task_done_callback is not None:
120
+ try:
121
+ self._task_done_callback(self)
122
+ except Exception as exc:
123
+ err_msg = f'Error executing return callback of task {self.name}: {str(exc)}\n'
124
+
125
+ return err_msg
126
+
111
127
  def init_log(self):
112
128
  if self.output_file is not None:
113
129
  self.fd = open(self.output_file, 'w')
@@ -232,7 +248,8 @@ class Client(object):
232
248
  print(f'Starting client {self.host} ...')
233
249
  try:
234
250
  self.conn, self.client = await asyncssh.create_connection(SSHClient, self.host, username=self.user,
235
- password=self.password)
251
+ password=self.password, agent_forwarding=True)
252
+ self.conn.set_keepalive(60, 3)
236
253
  except Exception:
237
254
  raise
238
255
  finally:
@@ -342,11 +359,7 @@ class Worker(object):
342
359
  self.status = WorkerStatus.IDLE
343
360
  return False, err_msg
344
361
 
345
- if task.done_callback is not None:
346
- try:
347
- task.done_callback()
348
- except Exception as exc:
349
- err_msg = f'Error executing return callback of task {self.name}: {str(exc)}\n'
362
+ err_msg = task.done_callback()
350
363
 
351
364
  self.status = WorkerStatus.IDLE
352
365
 
@@ -421,7 +434,7 @@ class WorkerPool(object):
421
434
  return worker
422
435
  await asyncio.sleep(0.1)
423
436
 
424
- def add(self, command, name=None, output_file=None, done_callback=None,
437
+ def add(self, command, name=None, output_file=None, task_done_callback=None, done_callback=None,
425
438
  run_on_host=None, n_try=3, pid_filename=None, keep_pid_file_on_error=False):
426
439
  """Add a command to execute by a worker in the pool. Optionally output result in output_file.
427
440
 
@@ -447,8 +460,8 @@ class WorkerPool(object):
447
460
  return
448
461
 
449
462
  self.tasks.append(Task(name, command, output_file=output_file, done_callback=done_callback,
450
- run_on_host=run_on_host, n_try=n_try, pid_filename=pid_filename,
451
- keep_pid_file_on_error=keep_pid_file_on_error))
463
+ task_done_callback=task_done_callback, run_on_host=run_on_host, n_try=n_try,
464
+ pid_filename=pid_filename, keep_pid_file_on_error=keep_pid_file_on_error))
452
465
 
453
466
  def get_all_tasks(self):
454
467
  tasks = collections.defaultdict(list)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "libpipe"
3
- version = "0.2"
3
+ version = "0.4"
4
4
  description = ""
5
5
  authors = ["\"Florent Mertens\" <\"florent.mertens@gmail.com\">"]
6
6
  license = "GPL-3.0-or-later"
@@ -18,7 +18,7 @@ entry_points = \
18
18
 
19
19
  setup_kwargs = {
20
20
  'name': 'libpipe',
21
- 'version': '0.2',
21
+ 'version': '0.4',
22
22
  'description': '',
23
23
  'long_description': 'Libpipe\n=======\n\nCommon pipeline framework and library\n\nInstallation\n------------\n\nlibpipe can be installed via pip:\n\n $ pip install libpipe\n\nand requires Python 3.6.0 or higher.\n',
24
24
  'author': '"Florent Mertens"',
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