1 __doc__ = """GNUmed worker threads."""
2
3 __author__ = "K.Hilbert <karsten.hilbert@gmx.net>"
4 __license__ = "GPL v2 or later"
5
6 import sys
7 import logging
8 import threading
9 import datetime as dt
10 import copy
11
12
13
14
15
16 if __name__ == '__main__':
17 sys.path.insert(0, '../../')
18
19
20 _log = logging.getLogger('gm.worker')
21
22
24 """Create a thread and have it execute <payload_function>.
25
26 <completion_callback> - if not None - better be prepared to
27 receive the result of <payload_function>.
28 """
29 _log.debug('worker [%s]', worker_name)
30
31 __payload_kwargs = copy.deepcopy(payload_kwargs)
32
33 worker_thread = None
34
35
36 def _run_payload():
37 try:
38 if payload_kwargs is None:
39 payload_result = payload_function()
40 else:
41 payload_result = payload_function(**__payload_kwargs)
42 _log.debug('finished running payload function')
43 except Exception:
44 _log.exception('error running payload function: %s', payload_function)
45 return
46 if completion_callback is None:
47 return
48 try:
49 completion_callback(payload_result)
50 _log.debug('finished running completion callback')
51 except Exception:
52 _log.exception('error running completion callback: %s', completion_callback)
53 _log.info('worker thread [name=%s, PID=%s] shuts down', worker_thread.name, worker_thread.ident)
54 return
55
56
57 if not callable(payload_function):
58 raise ValueError('<%s> is not callable', payload_function)
59 if completion_callback is not None:
60 if not callable(completion_callback):
61 raise ValueError('<%s> is not callable', completion_callback)
62 if worker_name is None:
63 __thread_name = dt.datetime.now().strftime('%f-%S')
64 else:
65 __thread_name = '%sThread-%s' % (
66 worker_name,
67 dt.datetime.now().strftime('%f')
68 )
69 _log.debug('creating thread "%s"', __thread_name)
70 _log.debug(' "%s" payload function: %s', __thread_name, payload_function)
71 _log.debug(' "%s" results callback: %s', __thread_name, completion_callback)
72
73 worker_thread = threading.Thread (
74 target = _run_payload,
75 name = __thread_name
76 )
77
78 worker_thread.daemon = True
79 _log.info('starting thread "%s"', __thread_name)
80 worker_thread.start()
81 _log.debug(' "%s" ident (= PID): %s', worker_thread.name, worker_thread.ident)
82
83
84
85
86 return worker_thread.ident
87
88
89
90
91 if __name__ == "__main__":
92
93 if len(sys.argv) < 2:
94 sys.exit()
95
96 if sys.argv[1] != 'test':
97 sys.exit()
98
99 import time
100 import random
101
102 from Gnumed.pycommon import gmLog2
103
105
106 def slowly_print_dots(info=None):
107 for i in range(5):
108 print('* (#%s in %s)' % (i, info))
109 time.sleep(1 + (random.random()*4))
110 return '%s' % time.localtime()
111
112 def print_dot_end_time(time_str):
113 print('done: %s' % time_str)
114
115 execute_in_worker_thread (
116 payload_function = slowly_print_dots,
117 payload_kwargs = {'info': ident},
118 completion_callback = print_dot_end_time
119 )
120
121 test_print_dots('A')
122 test_print_dots('B')
123