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.
- {libpipe-0.2 → libpipe-0.4}/PKG-INFO +1 -1
- {libpipe-0.2 → libpipe-0.4}/libpipe/tests/test_worker.py +38 -0
- {libpipe-0.2 → libpipe-0.4}/libpipe/worker.py +24 -11
- {libpipe-0.2 → libpipe-0.4}/pyproject.toml +1 -1
- {libpipe-0.2 → libpipe-0.4}/setup.py +1 -1
- {libpipe-0.2 → libpipe-0.4}/LICENSE +0 -0
- {libpipe-0.2 → libpipe-0.4}/README.md +0 -0
- {libpipe-0.2 → libpipe-0.4}/libpipe/__init__.py +0 -0
- {libpipe-0.2 → libpipe-0.4}/libpipe/attrmap.py +0 -0
- {libpipe-0.2 → libpipe-0.4}/libpipe/futils.py +0 -0
- {libpipe-0.2 → libpipe-0.4}/libpipe/msutils.py +0 -0
- {libpipe-0.2 → libpipe-0.4}/libpipe/settings.py +0 -0
- {libpipe-0.2 → libpipe-0.4}/libpipe/tests/__init__.py +0 -0
- {libpipe-0.2 → libpipe-0.4}/libpipe/tests/settings_test.toml +0 -0
- {libpipe-0.2 → libpipe-0.4}/libpipe/tests/test_settings.py +0 -0
- {libpipe-0.2 → libpipe-0.4}/libpipe/tools/__init__.py +0 -0
- {libpipe-0.2 → libpipe-0.4}/libpipe/tools/libnodes_bash.sh +0 -0
- {libpipe-0.2 → libpipe-0.4}/libpipe/tools/nodetool.py +0 -0
|
@@ -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.
|
|
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
|
-
|
|
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,
|
|
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)
|
|
@@ -18,7 +18,7 @@ entry_points = \
|
|
|
18
18
|
|
|
19
19
|
setup_kwargs = {
|
|
20
20
|
'name': 'libpipe',
|
|
21
|
-
'version': '0.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|