funboost 42.4__py3-none-any.whl → 42.6__py3-none-any.whl
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.
Potentially problematic release.
This version of funboost might be problematic. Click here for more details.
- funboost/__init__.py +1 -1
- funboost/consumers/base_consumer.py +12 -11
- funboost/core/booster.py +16 -0
- funboost/core/cli/discovery_boosters.py +18 -5
- funboost/core/cli/funboost_cli_user_templ.py +3 -5
- funboost/core/cli/funboost_fire.py +2 -2
- funboost/core/function_result_status_saver.py +11 -4
- funboost/function_result_web/__pycache__/functions.cpython-37.pyc +0 -0
- funboost/function_result_web/app.py +2 -2
- funboost/function_result_web/functions.py +9 -4
- funboost/function_result_web/templates/index.html +26 -7
- funboost/publishers/base_publisher.py +7 -0
- {funboost-42.4.dist-info → funboost-42.6.dist-info}/METADATA +1 -1
- {funboost-42.4.dist-info → funboost-42.6.dist-info}/RECORD +18 -18
- {funboost-42.4.dist-info → funboost-42.6.dist-info}/LICENSE +0 -0
- {funboost-42.4.dist-info → funboost-42.6.dist-info}/WHEEL +0 -0
- {funboost-42.4.dist-info → funboost-42.6.dist-info}/entry_points.txt +0 -0
- {funboost-42.4.dist-info → funboost-42.6.dist-info}/top_level.txt +0 -0
funboost/__init__.py
CHANGED
|
@@ -44,7 +44,7 @@ from apscheduler.executors.pool import ThreadPoolExecutor as ApschedulerThreadPo
|
|
|
44
44
|
from funboost.funboost_config_deafult import FunboostCommonConfig
|
|
45
45
|
from funboost.concurrent_pool.single_thread_executor import SoloExecutor
|
|
46
46
|
|
|
47
|
-
from funboost.core.function_result_status_saver import ResultPersistenceHelper, FunctionResultStatus
|
|
47
|
+
from funboost.core.function_result_status_saver import ResultPersistenceHelper, FunctionResultStatus, RunStatus
|
|
48
48
|
|
|
49
49
|
from funboost.core.helper_funs import delete_keys_and_return_new_dict, get_publish_time
|
|
50
50
|
|
|
@@ -524,10 +524,11 @@ class AbstractConsumer(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
524
524
|
current_retry_times = 0
|
|
525
525
|
function_only_params = delete_keys_and_return_new_dict(kw['body'])
|
|
526
526
|
for current_retry_times in range(max_retry_times + 1):
|
|
527
|
+
current_function_result_status.run_times = current_retry_times + 1
|
|
528
|
+
current_function_result_status.run_status = RunStatus.running
|
|
529
|
+
self._result_persistence_helper.save_function_result_to_mongo(current_function_result_status)
|
|
527
530
|
current_function_result_status = self._run_consuming_function_with_confirm_and_retry(kw, current_retry_times=current_retry_times,
|
|
528
|
-
function_result_status=
|
|
529
|
-
self.queue_name, self.consuming_function.__name__,
|
|
530
|
-
kw['body']))
|
|
531
|
+
function_result_status=current_function_result_status)
|
|
531
532
|
if (current_function_result_status.success is True or current_retry_times == max_retry_times
|
|
532
533
|
or current_function_result_status._has_requeue
|
|
533
534
|
or current_function_result_status._has_to_dlx_queue
|
|
@@ -538,7 +539,7 @@ class AbstractConsumer(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
538
539
|
time.sleep(self.consumer_params.retry_interval)
|
|
539
540
|
if not (current_function_result_status._has_requeue and self.BROKER_KIND in [BrokerEnum.RABBITMQ_AMQPSTORM, BrokerEnum.RABBITMQ_PIKA, BrokerEnum.RABBITMQ_RABBITPY]): # 已经nack了,不能ack,否则rabbitmq delevar tag 报错
|
|
540
541
|
self._confirm_consume(kw)
|
|
541
|
-
|
|
542
|
+
current_function_result_status.run_status = RunStatus.finish
|
|
542
543
|
self._result_persistence_helper.save_function_result_to_mongo(current_function_result_status)
|
|
543
544
|
if self._get_priority_conf(kw, 'do_task_filtering'):
|
|
544
545
|
self._redis_filter.add_a_value(function_only_params) # 函数执行成功后,添加函数的参数排序后的键值对字符串到set中。
|
|
@@ -597,7 +598,7 @@ class AbstractConsumer(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
597
598
|
function_only_params = delete_keys_and_return_new_dict(kw['body']) if self._do_not_delete_extra_from_msg is False else kw['body']
|
|
598
599
|
task_id = kw['body']['extra']['task_id']
|
|
599
600
|
t_start = time.time()
|
|
600
|
-
function_result_status.run_times = current_retry_times + 1
|
|
601
|
+
# function_result_status.run_times = current_retry_times + 1
|
|
601
602
|
try:
|
|
602
603
|
function_run = self.consuming_function
|
|
603
604
|
if self._consuming_function_is_asyncio:
|
|
@@ -679,20 +680,20 @@ class AbstractConsumer(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
679
680
|
current_retry_times = 0
|
|
680
681
|
function_only_params = delete_keys_and_return_new_dict(kw['body'])
|
|
681
682
|
for current_retry_times in range(max_retry_times + 1):
|
|
683
|
+
current_function_result_status.run_times = current_retry_times + 1
|
|
684
|
+
current_function_result_status.run_status = RunStatus.running
|
|
685
|
+
self._result_persistence_helper.save_function_result_to_mongo(current_function_result_status)
|
|
682
686
|
current_function_result_status = await self._async_run_consuming_function_with_confirm_and_retry(kw, current_retry_times=current_retry_times,
|
|
683
|
-
function_result_status=
|
|
684
|
-
self.queue_name, self.consuming_function.__name__,
|
|
685
|
-
kw['body'], ),
|
|
686
|
-
)
|
|
687
|
+
function_result_status=current_function_result_status )
|
|
687
688
|
if current_function_result_status.success is True or current_retry_times == max_retry_times or current_function_result_status._has_requeue:
|
|
688
689
|
break
|
|
689
690
|
else:
|
|
690
691
|
if self.consumer_params.retry_interval:
|
|
691
692
|
await asyncio.sleep(self.consumer_params.retry_interval)
|
|
692
693
|
|
|
693
|
-
# self._result_persistence_helper.save_function_result_to_mongo(function_result_status)
|
|
694
694
|
if not (current_function_result_status._has_requeue and self.BROKER_KIND in [BrokerEnum.RABBITMQ_AMQPSTORM, BrokerEnum.RABBITMQ_PIKA, BrokerEnum.RABBITMQ_RABBITPY]):
|
|
695
695
|
await simple_run_in_executor(self._confirm_consume, kw)
|
|
696
|
+
current_function_result_status.run_status = RunStatus.finish
|
|
696
697
|
await simple_run_in_executor(self._result_persistence_helper.save_function_result_to_mongo, current_function_result_status)
|
|
697
698
|
if self._get_priority_conf(kw, 'do_task_filtering'):
|
|
698
699
|
# self._redis_filter.add_a_value(function_only_params) # 函数执行成功后,添加函数的参数排序后的键值对字符串到set中。
|
funboost/core/booster.py
CHANGED
|
@@ -254,10 +254,23 @@ class BoostersManager:
|
|
|
254
254
|
booster = Booster(boost_params)(boost_params.consuming_function)
|
|
255
255
|
return booster
|
|
256
256
|
|
|
257
|
+
@classmethod
|
|
258
|
+
def push(cls, queue_name, *args, **kwargs):
|
|
259
|
+
"""push发布消息到消息队列 ;
|
|
260
|
+
"""
|
|
261
|
+
cls.get_or_create_booster_by_queue_name(queue_name).push(*args, **kwargs)
|
|
262
|
+
|
|
263
|
+
@classmethod
|
|
264
|
+
def publish(cls, queue_name, msg):
|
|
265
|
+
"""publish发布消息到消息队列;
|
|
266
|
+
"""
|
|
267
|
+
cls.get_or_create_booster_by_queue_name(queue_name).publish(msg)
|
|
268
|
+
|
|
257
269
|
@classmethod
|
|
258
270
|
def consume_queues(cls, *queue_names):
|
|
259
271
|
"""
|
|
260
272
|
启动多个消息队列名的消费,多个函数队列在当前同一个进程内启动消费.
|
|
273
|
+
这种方式节约总的内存,但无法利用多核cpu
|
|
261
274
|
"""
|
|
262
275
|
for queue_name in queue_names:
|
|
263
276
|
cls.get_booster(queue_name).consume()
|
|
@@ -269,6 +282,7 @@ class BoostersManager:
|
|
|
269
282
|
def consume_all_queues(cls):
|
|
270
283
|
"""
|
|
271
284
|
启动所有消息队列名的消费,无需一个一个函数亲自 funxx.consume()来启动,多个函数队列在当前同一个进程内启动消费.
|
|
285
|
+
这种方式节约总的内存,但无法利用多核cpu
|
|
272
286
|
"""
|
|
273
287
|
for queue_name in cls.get_all_queues():
|
|
274
288
|
cls.get_booster(queue_name).consume()
|
|
@@ -280,6 +294,7 @@ class BoostersManager:
|
|
|
280
294
|
def multi_process_consume_queues(cls, **queue_name__process_num):
|
|
281
295
|
"""
|
|
282
296
|
启动多个消息队列名的消费,传递队列名和进程数,每个队列启动n个单独的消费进程;
|
|
297
|
+
这种方式总的内存使用高,但充分利用多核cpu
|
|
283
298
|
例如 multi_process_consume_queues(queue1=2,queue2=3) 表示启动2个进程消费queue1,启动3个进程消费queue2
|
|
284
299
|
"""
|
|
285
300
|
for queue_name, process_num in queue_name__process_num.items():
|
|
@@ -292,6 +307,7 @@ class BoostersManager:
|
|
|
292
307
|
def multi_process_consume_all_queues(cls, process_num=1):
|
|
293
308
|
"""
|
|
294
309
|
启动所有消息队列名的消费,无需指定队列名,每个队列启动n个单独的消费进程;
|
|
310
|
+
这种方式总的内存使用高,但充分利用多核cpu
|
|
295
311
|
"""
|
|
296
312
|
for queue_name in cls.get_all_queues():
|
|
297
313
|
cls.get_booster(queue_name).multi_process_consume(process_num)
|
|
@@ -6,7 +6,10 @@ from pathlib import Path
|
|
|
6
6
|
import importlib.util
|
|
7
7
|
# import nb_log
|
|
8
8
|
from funboost.core.loggers import FunboostFileLoggerMixin
|
|
9
|
+
from funboost.utils.decorators import flyweight
|
|
9
10
|
|
|
11
|
+
|
|
12
|
+
@flyweight
|
|
10
13
|
class BoosterDiscovery(FunboostFileLoggerMixin):
|
|
11
14
|
def __init__(self, project_root_path: typing.Union[PathLike, str],
|
|
12
15
|
booster_dirs: typing.List[typing.Union[PathLike, str]],
|
|
@@ -23,6 +26,7 @@ class BoosterDiscovery(FunboostFileLoggerMixin):
|
|
|
23
26
|
self.py_file_re_str = py_file_re_str
|
|
24
27
|
|
|
25
28
|
self.py_files = []
|
|
29
|
+
self._has_discovery_import = False
|
|
26
30
|
|
|
27
31
|
def get_py_files_recursively(self, current_folder_path: Path, current_depth=0, ):
|
|
28
32
|
"""先找到所有py文件"""
|
|
@@ -34,15 +38,20 @@ class BoosterDiscovery(FunboostFileLoggerMixin):
|
|
|
34
38
|
elif item.suffix == '.py':
|
|
35
39
|
if self.py_file_re_str:
|
|
36
40
|
if re.search(self.py_file_re_str, str(item), ):
|
|
37
|
-
self.py_files.append(item)
|
|
41
|
+
self.py_files.append(str(item))
|
|
38
42
|
else:
|
|
39
|
-
self.py_files.append(item)
|
|
43
|
+
self.py_files.append(str(item))
|
|
40
44
|
self.py_files = list(set(self.py_files))
|
|
41
|
-
for f in self.py_files:
|
|
42
|
-
self.logger.debug(f)
|
|
43
45
|
|
|
44
46
|
def auto_discovery(self, ):
|
|
45
|
-
"""把所有py文件自动执行import,主要是把 所有的@boost函数装饰器注册到 pid_queue_name__booster_map 中
|
|
47
|
+
"""把所有py文件自动执行import,主要是把 所有的@boost函数装饰器注册到 pid_queue_name__booster_map 中
|
|
48
|
+
这个auto_discovery方法最好放到main里面,如果要扫描自身文件夹,没写正则排除文件本身,会无限懵逼死循环导入,无无限懵逼死循环导入
|
|
49
|
+
"""
|
|
50
|
+
if self._has_discovery_import is False:
|
|
51
|
+
self._has_discovery_import = True
|
|
52
|
+
else:
|
|
53
|
+
pass
|
|
54
|
+
return # 这一个判断是避免用户执行BoosterDiscovery.auto_discovery没有放到 if __name__ == '__main__'中,导致无限懵逼死循环.
|
|
46
55
|
self.logger.info(self.booster__full_path_dirs)
|
|
47
56
|
for dir in self.booster__full_path_dirs:
|
|
48
57
|
if not Path(dir).exists():
|
|
@@ -50,6 +59,10 @@ class BoosterDiscovery(FunboostFileLoggerMixin):
|
|
|
50
59
|
|
|
51
60
|
self.get_py_files_recursively(Path(dir))
|
|
52
61
|
for file_path in self.py_files:
|
|
62
|
+
self.logger.debug(f'导入模块 {file_path}')
|
|
63
|
+
if Path(file_path) == Path(sys._getframe(1).f_code.co_filename):
|
|
64
|
+
self.logger.warning(f'排除导入调用auto_discovery的模块自身 {file_path}') # 否则下面的import这个文件,会造成无限懵逼死循环
|
|
65
|
+
continue
|
|
53
66
|
spec = importlib.util.spec_from_file_location('module', file_path)
|
|
54
67
|
module = importlib.util.module_from_spec(spec)
|
|
55
68
|
spec.loader.exec_module(module)
|
|
@@ -30,12 +30,10 @@ from funboost.core.cli.discovery_boosters import BoosterDiscovery
|
|
|
30
30
|
'''
|
|
31
31
|
env_dict['project_root_path'] = project_root_path
|
|
32
32
|
|
|
33
|
-
# booster_dirs 用户可以自己增加扫描的文件夹,这样可以命令行少传了 --booster_dirs_str
|
|
34
|
-
# BoosterDiscovery 可以多吃调用
|
|
35
|
-
BoosterDiscovery(project_root_path, booster_dirs=[], max_depth=1,py_file_re_str=None).auto_discovery()
|
|
36
|
-
|
|
37
|
-
|
|
38
33
|
if __name__ == '__main__':
|
|
34
|
+
# booster_dirs 用户可以自己增加扫描的文件夹,这样可以命令行少传了 --booster_dirs_str
|
|
35
|
+
# BoosterDiscovery 可以多次调用
|
|
36
|
+
BoosterDiscovery(project_root_path, booster_dirs=[], max_depth=1, py_file_re_str=None).auto_discovery() # 这个最好放到main里面,如果要扫描自身文件夹,没写正则排除文件本身,会无限懵逼死循环导入
|
|
39
37
|
fire.Fire(BoosterFire, )
|
|
40
38
|
|
|
41
39
|
'''
|
|
@@ -60,7 +60,7 @@ class BoosterFire(object):
|
|
|
60
60
|
或者 push add_queue --x=1 --y=2;
|
|
61
61
|
或者 push add_queue -x 1 -y 2;
|
|
62
62
|
"""
|
|
63
|
-
BoostersManager.
|
|
63
|
+
BoostersManager.push(queue_name,*args, **kwargs)
|
|
64
64
|
return self
|
|
65
65
|
|
|
66
66
|
def __str__(self):
|
|
@@ -73,7 +73,7 @@ class BoosterFire(object):
|
|
|
73
73
|
publish add_queue "{'x':1,'y':2}"
|
|
74
74
|
"""
|
|
75
75
|
|
|
76
|
-
BoostersManager.
|
|
76
|
+
BoostersManager.publish(queue_name,msg)
|
|
77
77
|
return self
|
|
78
78
|
|
|
79
79
|
def consume_queues(self, *queue_names: str):
|
|
@@ -20,6 +20,9 @@ from funboost.utils.mongo_util import MongoMixin
|
|
|
20
20
|
# from nb_log import LoggerMixin
|
|
21
21
|
from funboost.core.loggers import FunboostFileLoggerMixin
|
|
22
22
|
|
|
23
|
+
class RunStatus:
|
|
24
|
+
running = 'running'
|
|
25
|
+
finish = 'finish'
|
|
23
26
|
|
|
24
27
|
class FunctionResultStatus():
|
|
25
28
|
host_name = socket.gethostname()
|
|
@@ -51,6 +54,7 @@ class FunctionResultStatus():
|
|
|
51
54
|
self.time_cost = None
|
|
52
55
|
self.time_end = None
|
|
53
56
|
self.success = False
|
|
57
|
+
self.run_status = ''
|
|
54
58
|
self.total_thread = threading.active_count()
|
|
55
59
|
self._has_requeue = False
|
|
56
60
|
self._has_to_dlx_queue = False
|
|
@@ -59,11 +63,14 @@ class FunctionResultStatus():
|
|
|
59
63
|
|
|
60
64
|
def get_status_dict(self, without_datetime_obj=False):
|
|
61
65
|
self.time_end = time.time()
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
if self.run_status == RunStatus.running:
|
|
67
|
+
self.time_cost = None
|
|
68
|
+
else:
|
|
69
|
+
self.time_cost = round(self.time_end - self.time_start, 3)
|
|
70
|
+
item = {}
|
|
71
|
+
for k, v in self.__dict__.items():
|
|
65
72
|
if not k.startswith('_'):
|
|
66
|
-
item[k] =v
|
|
73
|
+
item[k] = v
|
|
67
74
|
item['host_name'] = self.host_name
|
|
68
75
|
item['host_process'] = self.host_process
|
|
69
76
|
item['script_name'] = self.script_name
|
|
Binary file
|
|
@@ -119,7 +119,7 @@ def query_cols_view():
|
|
|
119
119
|
@app.route('/query_result')
|
|
120
120
|
@login_required
|
|
121
121
|
def query_result_view():
|
|
122
|
-
|
|
122
|
+
|
|
123
123
|
return jsonify(query_result(**request.values.to_dict()))
|
|
124
124
|
|
|
125
125
|
|
|
@@ -142,7 +142,7 @@ if __name__ == '__main__':
|
|
|
142
142
|
# with app.test_request_context():
|
|
143
143
|
# print(url_for('query_cols_view'))
|
|
144
144
|
|
|
145
|
-
app.run(debug=False, threaded=True, host='0.0.0.0', port=
|
|
145
|
+
app.run(debug=False, threaded=True, host='0.0.0.0', port=27019)
|
|
146
146
|
|
|
147
147
|
'''
|
|
148
148
|
linux 是export , win是 set
|
|
@@ -6,7 +6,7 @@ import json
|
|
|
6
6
|
from pprint import pprint
|
|
7
7
|
import time
|
|
8
8
|
from flask import jsonify
|
|
9
|
-
|
|
9
|
+
import copy
|
|
10
10
|
from funboost import nb_print
|
|
11
11
|
from funboost.utils import time_util, decorators, LoggerMixin
|
|
12
12
|
from funboost.utils.mongo_util import MongoMixin
|
|
@@ -36,6 +36,10 @@ def get_cols(col_name_search: str):
|
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
def query_result(col_name, start_time, end_time, is_success, function_params: str, page, ):
|
|
39
|
+
query_kw = copy.copy(locals())
|
|
40
|
+
t0 = time.time()
|
|
41
|
+
if not col_name:
|
|
42
|
+
return []
|
|
39
43
|
db = MongoMixin().mongo_db_task_status
|
|
40
44
|
condition = {
|
|
41
45
|
'insert_time': {'$gt': time_util.DatetimeConverter(start_time).datetime_obj,
|
|
@@ -56,7 +60,8 @@ def query_result(col_name, start_time, end_time, is_success, function_params: st
|
|
|
56
60
|
# results = list(db.get_collection(col_name).find(condition, ).sort([('insert_time', -1)]).skip(int(page) * 100).limit(100))
|
|
57
61
|
# with decorators.TimerContextManager():
|
|
58
62
|
results = list(db.get_collection(col_name).find(condition, {'insert_time': 0, 'utime': 0}).skip(int(page) * 100).limit(100))
|
|
59
|
-
# nb_print(
|
|
63
|
+
# nb_print(results)
|
|
64
|
+
nb_print(time.time() -t0, query_kw)
|
|
60
65
|
return results
|
|
61
66
|
|
|
62
67
|
|
|
@@ -73,8 +78,8 @@ def get_speed(col_name, start_time, end_time):
|
|
|
73
78
|
with decorators.TimerContextManager():
|
|
74
79
|
# success_num = db.get_collection(col_name).count({**{'success': True}, **condition})
|
|
75
80
|
# fail_num = db.get_collection(col_name).count({**{'success': False}, **condition})
|
|
76
|
-
success_num = db.get_collection(col_name).count_documents({**{'success': True}, **condition})
|
|
77
|
-
fail_num = db.get_collection(col_name).count_documents({**{'success': False}, **condition})
|
|
81
|
+
success_num = db.get_collection(col_name).count_documents({**{'success': True,'run_status':'finish'}, **condition})
|
|
82
|
+
fail_num = db.get_collection(col_name).count_documents({**{'success': False,'run_status':'finish'}, **condition})
|
|
78
83
|
qps = (success_num + fail_num) / (time_util.DatetimeConverter(end_time).timestamp - time_util.DatetimeConverter(start_time).timestamp)
|
|
79
84
|
return {'success_num': success_num, 'fail_num': fail_num, 'qps': round(qps, 1)}
|
|
80
85
|
|
|
@@ -123,7 +123,8 @@
|
|
|
123
123
|
|
|
124
124
|
|
|
125
125
|
</main><!-- page-content" --></div><!-- page-wrapper -->
|
|
126
|
-
|
|
126
|
+
<!--<script src="{{ url_for('static',filename='js/jquery-1.11.0.min.js') }}" type="text/javascript"></script>-->
|
|
127
|
+
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
|
|
127
128
|
<script src="http://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
|
128
129
|
|
|
129
130
|
|
|
@@ -163,6 +164,7 @@
|
|
|
163
164
|
return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
|
|
166
168
|
//昨天的时间
|
|
167
169
|
var day1 = new Date();
|
|
168
170
|
day1.setDate(day1.getDate() - 2);
|
|
@@ -220,16 +222,19 @@
|
|
|
220
222
|
var html = ' <thead>\n' +
|
|
221
223
|
' <tr>\n' +
|
|
222
224
|
' <th>执行机器-进程-脚本</th>\n' +
|
|
223
|
-
|
|
225
|
+
|
|
224
226
|
' <th>函数名称</th>\n' +
|
|
225
227
|
' <th>函数入参</th>\n' +
|
|
226
228
|
' <th>函数结果</th>\n' +
|
|
227
|
-
' <th
|
|
228
|
-
' <th
|
|
229
|
+
' <th>消息发布时间</th>\n' +
|
|
230
|
+
' <th>开始执行时间</th>\n' +
|
|
231
|
+
' <th>消耗时间(秒)</th>\n' +
|
|
232
|
+
' <th>执行次数(重试)</th>\n' +
|
|
233
|
+
' <th>运行状态</th>\n' +
|
|
229
234
|
' <th>是否成功</th>\n' +
|
|
230
235
|
' <th>错误原因</th>\n' +
|
|
231
236
|
|
|
232
|
-
|
|
237
|
+
|
|
233
238
|
' <th>线程(协程)数</th>\n' +
|
|
234
239
|
' </tr>\n' +
|
|
235
240
|
' </thead>' +
|
|
@@ -257,11 +262,25 @@
|
|
|
257
262
|
' <td>{9}</td>\n' +
|
|
258
263
|
' <td>{10}</td>\n' +
|
|
259
264
|
' <td>{11}</td>\n' +
|
|
265
|
+
' <td>{12}</td>\n' +
|
|
260
266
|
|
|
261
267
|
' </tr>';
|
|
262
268
|
var successText = item.success === true ? "成功" : "失败";
|
|
263
|
-
|
|
264
|
-
|
|
269
|
+
<!-- console.info(item.run_status);-->
|
|
270
|
+
var run_status_text = item.run_status;
|
|
271
|
+
if (item.run_status==="running"){
|
|
272
|
+
successText = "未完成";
|
|
273
|
+
displayLevel = "info";
|
|
274
|
+
if ( Date.now() /1000 - item.time_start > 600) {
|
|
275
|
+
run_status_text = "running?";
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
var time_start_obj = new Date(item.time_start * 1000);
|
|
280
|
+
var time_start_str = dateToString(time_start_obj);
|
|
281
|
+
|
|
282
|
+
tr = tr.format(displayLevel, item.host_process + ' - ' + item.script_name, item.function, item.params_str, item.result,item.publish_time_str,
|
|
283
|
+
time_start_str,item.time_cost, item.run_times, run_status_text,successText, item.exception, item.total_thread);
|
|
265
284
|
html += tr;
|
|
266
285
|
}
|
|
267
286
|
html += '</tbody>';
|
|
@@ -223,6 +223,13 @@ class AbstractPublisher(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
223
223
|
self._init_count()
|
|
224
224
|
return AsyncResult(task_id)
|
|
225
225
|
|
|
226
|
+
def send_msg(self,msg:typing.Union[dict,str]):
|
|
227
|
+
"""直接发送任意消息内容到消息队列,不生成辅助参数,无视函数入参名字,不校验入参个数和键名"""
|
|
228
|
+
if isinstance(msg,dict):
|
|
229
|
+
msg = json.dumps(msg, ensure_ascii=False)
|
|
230
|
+
decorators.handle_exception(retry_times=10, is_throw_error=True, time_sleep=0.1)(
|
|
231
|
+
self.concrete_realization_of_publish)(msg)
|
|
232
|
+
|
|
226
233
|
def push(self, *func_args, **func_kwargs):
|
|
227
234
|
"""
|
|
228
235
|
简写,只支持传递消费函数的本身参数,不支持priority_control_config参数。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: funboost
|
|
3
|
-
Version: 42.
|
|
3
|
+
Version: 42.6
|
|
4
4
|
Summary: pip install funboost,python全功能分布式函数调度框架,。支持python所有类型的并发模式和一切知名消息队列中间件,支持如 celery dramatiq等框架整体作为funboost中间件,python函数加速器,框架包罗万象,用户能想到的控制功能全都有。一统编程思维,兼容50% python业务场景,适用范围广。只需要一行代码即可分布式执行python一切函数,99%用过funboost的pythoner 感受是 简易 方便 强劲 强大,相见恨晚
|
|
5
5
|
Home-page: https://github.com/ydf0509/funboost
|
|
6
6
|
Author: bfzs
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
funboost/__init__.py,sha256=
|
|
1
|
+
funboost/__init__.py,sha256=5gHRofQPfikA7jOf5Hj1kucFcHajOIh_ChMQH_oIurw,3766
|
|
2
2
|
funboost/__init__old.py,sha256=07A1MLsxLtuRQQOIfDyphddOwNBrGe34enoHWAnjV14,20379
|
|
3
3
|
funboost/__main__.py,sha256=-6Nogi666Y0LN8fVm3JmHGTOk8xEGWvotW_GDbSaZME,1065
|
|
4
4
|
funboost/constant.py,sha256=haAbx2cvTN9itPzBG4v3_ODIi1-RudvBj6s_QjniqjU,7162
|
|
@@ -33,7 +33,7 @@ funboost/concurrent_pool/backup/async_pool_executor0223.py,sha256=RVUZiylUvpTm6U
|
|
|
33
33
|
funboost/concurrent_pool/backup/async_pool_executor_back.py,sha256=KL6zEQaa1KkZOlAO85mCC1gwLm-YC5Ghn21IUom0UKM,9598
|
|
34
34
|
funboost/concurrent_pool/backup/async_pool_executor_janus.py,sha256=OHMWJ9l3EYTpPpcrPrGGKd4K0tmQ2PN8HiX0Dta0EOo,5728
|
|
35
35
|
funboost/consumers/__init__.py,sha256=ZXY_6Kut1VYNQiF5aWEgIWobsW1ht9YUP0TdRZRWFqI,126
|
|
36
|
-
funboost/consumers/base_consumer.py,sha256=
|
|
36
|
+
funboost/consumers/base_consumer.py,sha256=qgy9M8ibPl2GFI4JLsRDSPLZTNyoIaxRG4tjSzmroVw,72875
|
|
37
37
|
funboost/consumers/celery_consumer.py,sha256=W25gbGyimf8KG5lLbtgar3Ix7F3O4cIRBLtRq8nJ0AE,9216
|
|
38
38
|
funboost/consumers/confirm_mixin.py,sha256=eY6fNwx51Hn4bQSYRjyTRwOqfCGsikVnd2Ga_Ep31N4,6062
|
|
39
39
|
funboost/consumers/dramatiq_consumer.py,sha256=ozmeAfeF0U-YNYHK4suQB0N264h5AZdfMH0O45Mh-8A,2229
|
|
@@ -81,12 +81,12 @@ funboost/contrib/redis_consume_latest_msg_broker.py,sha256=ESortBZ2qu_4PBCa3e3Fe
|
|
|
81
81
|
funboost/contrib/save_result_status_to_sqldb.py,sha256=AxvD7nHs4sjr9U0kwEZzyPKrsGdU_JzEgzzhh_V1_4w,4071
|
|
82
82
|
funboost/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
83
83
|
funboost/core/active_cousumer_info_getter.py,sha256=09fEc-BTEIRfDDfHmOvKnMjLjtOyp4edLsUlAXUR_Qs,4966
|
|
84
|
-
funboost/core/booster.py,sha256=
|
|
84
|
+
funboost/core/booster.py,sha256=k6UPxfW7QdhfdVu9yprHkF46jLO2eXTqTZPYkukmyZc,15741
|
|
85
85
|
funboost/core/exceptions.py,sha256=pLF7BkRJAfDiWp2_xGZqencmwdPiSQI1NENbImExknY,1311
|
|
86
86
|
funboost/core/fabric_deploy_helper.py,sha256=KPjifNy1G1tDOT2eaR0X8hegot0HUk5vF-P1DnhxME4,8941
|
|
87
87
|
funboost/core/func_params_model.py,sha256=jVPWke_UpwZ_Ik28_dL_j8h2dSrtYlEFTtUWMIw2KCA,17594
|
|
88
88
|
funboost/core/function_result_status_config.py,sha256=PyjqAQOiwsLt28sRtH-eYRjiI3edPFO4Nde0ILFRReE,1764
|
|
89
|
-
funboost/core/function_result_status_saver.py,sha256=
|
|
89
|
+
funboost/core/function_result_status_saver.py,sha256=UdokGSwU630t70AZnT9Ecj7GpYXORBDivlc9kadoI2E,9172
|
|
90
90
|
funboost/core/helper_funs.py,sha256=M9Ad9EzgHdP581X-vuFgCavJRoezLGXlXSFg7zyMWD0,1578
|
|
91
91
|
funboost/core/kill_remote_task.py,sha256=MZ5vWLGt6SxyN76h5Lf_id9tyVUzjR-qXNyJwXaGlZY,8129
|
|
92
92
|
funboost/core/loggers.py,sha256=173aXdqE8nAe8t6OcVMNAFsCUClVrWQovdQhTAg9IyM,2407
|
|
@@ -94,17 +94,17 @@ funboost/core/msg_result_getter.py,sha256=oZDuLDR5XQNzzvgDTsA7wroICToPwrkU9-OAaX
|
|
|
94
94
|
funboost/core/muliti_process_enhance.py,sha256=0wgy8qnxfg_g-BtlKfysH6TZ9s97EWTdLFVWPAVUGw0,3601
|
|
95
95
|
funboost/core/try_get_user_funboost_common_config.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
96
96
|
funboost/core/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
97
|
-
funboost/core/cli/discovery_boosters.py,sha256=
|
|
98
|
-
funboost/core/cli/funboost_cli_user_templ.py,sha256=
|
|
99
|
-
funboost/core/cli/funboost_fire.py,sha256=
|
|
97
|
+
funboost/core/cli/discovery_boosters.py,sha256=68SUEQnN3KN8_mfLHN2ho1z02vHAA-gHhTGfUAf4kz8,3811
|
|
98
|
+
funboost/core/cli/funboost_cli_user_templ.py,sha256=XUpKLxRKtYfebPUM8wii64kB0HW8L7j9LnRpT0xCfQI,2243
|
|
99
|
+
funboost/core/cli/funboost_fire.py,sha256=OT0SNi9Zb0Tom2E0cWuArQs0obUowAA_rpCF7GdaKPs,5065
|
|
100
100
|
funboost/factories/__init__.py,sha256=s7kKKjR1HU5eMjPD6r5b-SXTVMo1zBp2JjOAtkyt5Yo,178
|
|
101
101
|
funboost/factories/broker_kind__publsiher_consumer_type_map.py,sha256=2fWuNVDOYbs8CCrQnQtWIc3wwQ5a9AOFEd7-cufj3I8,9630
|
|
102
102
|
funboost/factories/consumer_factory.py,sha256=rPceMsUr2mrcFXL-_3kQGknNiADjfgTh9wXG1qd8yAw,1041
|
|
103
103
|
funboost/factories/publisher_factotry.py,sha256=JOvECeovdDRXWvh_dqnNoXX-A3M9vUjVRMCpaCl_R_Q,2040
|
|
104
|
-
funboost/function_result_web/app.py,sha256=
|
|
105
|
-
funboost/function_result_web/functions.py,sha256=
|
|
104
|
+
funboost/function_result_web/app.py,sha256=DhUZFi083KILEc5WGCGkuYQ9fiHa8nB6curt6TSa7EQ,4975
|
|
105
|
+
funboost/function_result_web/functions.py,sha256=dXGUD9H62RdE6DN53tVm16tjEUNLD52Sg9YC5Loh6G4,7541
|
|
106
106
|
funboost/function_result_web/__pycache__/app.cpython-37.pyc,sha256=p-jwU7xf31KOJhmhNXqj6J79PTxjMbiTU16gAotpSEw,4045
|
|
107
|
-
funboost/function_result_web/__pycache__/functions.cpython-37.pyc,sha256=
|
|
107
|
+
funboost/function_result_web/__pycache__/functions.cpython-37.pyc,sha256=vEXI6a8iSONHTW49VOpm9kaaoW4xGuP4JpxlrIXHHzs,4117
|
|
108
108
|
funboost/function_result_web/static/assets/css/custom.css,sha256=3brvjy2aBOTIXcTUK4NV6dX5wFRqx6K2aLu_jQn63jM,7674
|
|
109
109
|
funboost/function_result_web/static/assets/css/jquery.mCustomScrollbar.min.css,sha256=JHGEmB629pipTkMag9aMaw32I8zle24p3FpsEeI6oZU,42839
|
|
110
110
|
funboost/function_result_web/static/assets/img/user.jpg,sha256=Vz1A99gho-0bKV67Pt2s_zT25mWhNcPe0mWG-0mRl9U,23610
|
|
@@ -116,10 +116,10 @@ funboost/function_result_web/static/images/password.png,sha256=0jRivuQAhWKtkS73p
|
|
|
116
116
|
funboost/function_result_web/static/images/tick.png,sha256=S9dZYN4HQzw7JsWPw3ut1dQp4OTJ_Uh2Qp2KUDF1Jv8,2912
|
|
117
117
|
funboost/function_result_web/static/images/user.png,sha256=HxLjNc83WZzZEscZRdmVhGKlPXNdp_EKmmYxafuyb3g,622
|
|
118
118
|
funboost/function_result_web/static/js/jquery-1.11.0.min.js,sha256=ryQZ3RXgnqkTz-lNEw-YcEhnMuV3ZODwLqOEbyBBRu4,96383
|
|
119
|
-
funboost/function_result_web/templates/index.html,sha256=
|
|
119
|
+
funboost/function_result_web/templates/index.html,sha256=YM0582Q4t2da-xBf3Ga0McIfcsT9H98rjZck-irMkGo,20387
|
|
120
120
|
funboost/function_result_web/templates/login.html,sha256=q37dj7O0LeyiV38Zd5P1Qn_qmhjdFomuYTRY1Yk48Bo,2007
|
|
121
121
|
funboost/publishers/__init__.py,sha256=xqBHlvsJQVPfbdvP84G0LHmVB7-pFBS7vDnX1Uo9pVY,131
|
|
122
|
-
funboost/publishers/base_publisher.py,sha256=
|
|
122
|
+
funboost/publishers/base_publisher.py,sha256=sWpSDG5BfUrI7wTQ-3FX_dqaHXL5Or8axcmLAglUEG0,14944
|
|
123
123
|
funboost/publishers/celery_publisher.py,sha256=uc9N1uLW74skUCw8dsnvxORM2O3cy4SiI7tUZRmvkHA,2336
|
|
124
124
|
funboost/publishers/celery_publisher000.py,sha256=2XLOyU2__vlIUTi5L15uf0BJqAIjxbc3kCLIRDSOY9w,3966
|
|
125
125
|
funboost/publishers/confluent_kafka_publisher.py,sha256=gC4SUk6I_7zjSngcbTI7oTJ7sza3oE3PE19KQkwCpn4,4802
|
|
@@ -261,9 +261,9 @@ funboost/utils/pysnooper_ydf/utils.py,sha256=evSmGi_Oul7vSP47AJ0DLjFwoCYCfunJZ1m
|
|
|
261
261
|
funboost/utils/pysnooper_ydf/variables.py,sha256=QejRDESBA06KG9OH4sBT4J1M55eaU29EIHg8K_igaXo,3693
|
|
262
262
|
funboost/utils/times/__init__.py,sha256=Y4bQD3SIA_E7W2YvHq2Qdi0dGM4H2DxyFNdDOuFOq1w,2417
|
|
263
263
|
funboost/utils/times/version.py,sha256=11XfnZVVzOgIhXXdeN_mYfdXThfrsbQHpA0wCjz-hpg,17
|
|
264
|
-
funboost-42.
|
|
265
|
-
funboost-42.
|
|
266
|
-
funboost-42.
|
|
267
|
-
funboost-42.
|
|
268
|
-
funboost-42.
|
|
269
|
-
funboost-42.
|
|
264
|
+
funboost-42.6.dist-info/LICENSE,sha256=9EPP2ktG_lAPB8PjmWV-c9BiaJHc_FP6pPLcUrUwx0E,11562
|
|
265
|
+
funboost-42.6.dist-info/METADATA,sha256=LJFS2m_BYI8k0nOIAYowA5S8WquCeKqz-lULFs-M5uM,30477
|
|
266
|
+
funboost-42.6.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
|
267
|
+
funboost-42.6.dist-info/entry_points.txt,sha256=yMSSAGRzRAAhGyNNQHw24MooKlDZsaJ499_D6fPl58A,96
|
|
268
|
+
funboost-42.6.dist-info/top_level.txt,sha256=K8WuKnS6MRcEWxP1NvbmCeujJq6TEfbsB150YROlRw0,9
|
|
269
|
+
funboost-42.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|