import threadpool
import threading
import time
class FuncTTLMonitorDecorator(object):
class _ResultThread(threading.Thread):
def __init__(self, target, *args, **kwargs):
super().__init__(daemon=True)
self.func = target
self.args = args
self.kwargs = kwargs
self.result = None
def run(self):
self.result = self.func(*self.args, **self.kwargs)
def get_result(self):
try:
return self.result
except Exception as e:
return None
def __init__(self, ttl, result_parse_func=None):
self.ttl = int(ttl)
self.result_parse_func = result_parse_func
def run(self, func, *args, **kwargs) -> dict:
"""
:param func:
:param args:
:param kwargs:
:return: 参数原样返回
"""
result = {
'has_ttl': True,
'ttl': self.ttl,
'success': False,
'error': f'The function {func.__name__}(...) timeout({self.ttl} seconds)',
'args': args,
'kwargs': kwargs,
'data': None
}
_t = self._ResultThread(func, *args, **kwargs)
for i in range(self.ttl):
time.sleep(1)
if not _t.get_result():
continue
result.update(success=True, error='', data=_t.get_result())
break
if self.result_parse_func:
return self.result_parse_func(result)
return result
def __call__(self, func):
def wrapper(*args, **kwargs):
return self.run(func, *args, **kwargs)
return wrapper
def general_login(args_dict, times=1):
device = args_dict.get('device')
try:
while True:
time.sleep(1)
except Exception as e:
device.update(error=str(e), success=False)
return device
def ttl_result_parse(result):
if not result.get('has_ttl'):
return result
if result.get('success'):
data = result.get('data')
else:
data = result.get('args')[0].get('device')
data.update(success=False, error=result.get('error'))
return data
if __name__ == '__main__':
pool = threadpool.ThreadPool(2)
args_list = [
{'device': {'ip': '10.100.235.9', 'brand': 'Aruba', 'model': '7210', 'device_type': 'aruba_os'},
'commands': ['show running-config']
},
{
'device': {'ip': '10.100.235.10', 'brand': 'Aruba', 'model': '7210', 'device_type': 'aruba_os'},
'commands': ['show running-config']
},
{
'device': {'ip': '10.100.235.1', 'brand': 'Aruba', 'model': '7210', 'device_type': 'aruba_os'},
'commands': ['show running-config']
}
]
results = []
tasks = threadpool.makeRequests(
callable_=FuncTTLMonitorDecorator(ttl=3, result_parse_func=ttl_result_parse)(general_login),
args_list=args_list,
callback=lambda req, res: results.append(res)
)
[pool.putRequest(task) for task in tasks]
pool.wait()
import json
print(json.dumps(results, indent=4))