Package Gnumed :: Package pycommon :: Module gmWorkerThread
[frames] | no frames]

Source Code for Module Gnumed.pycommon.gmWorkerThread

  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  # wx.CallAfter() does not seem to work with multiprocessing ! 
 13  #import multiprocessing 
 14   
 15   
 16  if __name__ == '__main__': 
 17          sys.path.insert(0, '../../') 
 18   
 19   
 20  _log = logging.getLogger('gm.worker') 
 21   
 22  #===================================================================== 
23 -def execute_in_worker_thread(payload_function=None, payload_kwargs=None, completion_callback=None, worker_name=None):
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 # decouple from calling thread 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: %s', 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 #worker_thread = multiprocessing.Process ( 73 worker_thread = threading.Thread ( 74 target = _run_payload, 75 name = __thread_name 76 ) 77 # we don't want hung workers to prevent us from exiting GNUmed 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 # from here on, another thread executes _run_payload() 83 # which executes payload_function() and, eventually, 84 # completion_callback() if available, 85 # return thread ident so people can join() it if needed 86 return worker_thread.ident 87 88 #===================================================================== 89 # main 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
104 - def test_print_dots(ident=None):
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