funboost 45.3__py3-none-any.whl → 45.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 +2 -2
- funboost/assist/faststream_helper.py +18 -0
- funboost/assist/taskiq_helper.py +1 -0
- funboost/consumers/base_consumer.py +17 -12
- funboost/consumers/confirm_mixin.py +2 -2
- funboost/consumers/faststream_consumer.py +54 -0
- funboost/consumers/local_python_queue_consumer.py +2 -2
- funboost/consumers/redis_consumer.py +2 -2
- funboost/consumers/redis_consumer_ack_using_timeout.py +2 -2
- funboost/consumers/redis_consumer_simple.py +2 -1
- funboost/consumers/redis_filter.py +2 -2
- funboost/core/current_task.py +1 -1
- funboost/core/func_params_model.py +2 -4
- funboost/core/function_result_status_saver.py +5 -3
- funboost/core/msg_result_getter.py +3 -3
- funboost/core/serialization.py +16 -0
- funboost/factories/broker_kind__publsiher_consumer_type_map.py +14 -6
- funboost/publishers/base_publisher.py +31 -17
- funboost/publishers/faststream_publisher.py +57 -0
- funboost/publishers/local_python_queue_publisher.py +9 -7
- funboost/queues/memory_queues_map.py +11 -0
- funboost/utils/json_helper.py +14 -14
- {funboost-45.3.dist-info → funboost-45.6.dist-info}/METADATA +21 -9
- {funboost-45.3.dist-info → funboost-45.6.dist-info}/RECORD +28 -22
- {funboost-45.3.dist-info → funboost-45.6.dist-info}/LICENSE +0 -0
- {funboost-45.3.dist-info → funboost-45.6.dist-info}/WHEEL +0 -0
- {funboost-45.3.dist-info → funboost-45.6.dist-info}/entry_points.txt +0 -0
- {funboost-45.3.dist-info → funboost-45.6.dist-info}/top_level.txt +0 -0
funboost/__init__.py
CHANGED
|
@@ -13,7 +13,7 @@ set_frame_config这个模块的 use_config_form_funboost_config_module() 是核
|
|
|
13
13
|
这段注释说明和使用的用户无关,只和框架开发人员有关.
|
|
14
14
|
'''
|
|
15
15
|
|
|
16
|
-
__version__ = "45.
|
|
16
|
+
__version__ = "45.6"
|
|
17
17
|
|
|
18
18
|
from funboost.set_frame_config import show_frame_config
|
|
19
19
|
|
|
@@ -65,5 +65,5 @@ from funboost.core.current_task import funboost_current_task
|
|
|
65
65
|
# set_interrupt_signal_handler()
|
|
66
66
|
|
|
67
67
|
# 有的包默认没加handlers,原始的日志不漂亮且不可跳转不知道哪里发生的。这里把warnning级别以上的日志默认加上handlers。
|
|
68
|
-
# nb_log.get_logger(name='', log_level_int=30,
|
|
68
|
+
# nb_log.get_logger(name='', log_level_int=30, log_filename='pywarning.log')
|
|
69
69
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
|
|
3
|
+
from faststream import FastStream
|
|
4
|
+
from faststream.rabbit import RabbitBroker
|
|
5
|
+
from funboost.funboost_config_deafult import BrokerConnConfig
|
|
6
|
+
from funboost.core.loggers import get_funboost_file_logger
|
|
7
|
+
|
|
8
|
+
get_funboost_file_logger('faststream.access.rabbit')
|
|
9
|
+
|
|
10
|
+
broker = RabbitBroker(BrokerConnConfig.RABBITMQ_URL, max_consumers=20)
|
|
11
|
+
app = FastStream(broker)
|
|
12
|
+
|
|
13
|
+
# asyncio.get_event_loop().run_until_complete(broker.connect())
|
|
14
|
+
#
|
|
15
|
+
# asyncio.get_event_loop().run_until_complete(broker.start())
|
|
16
|
+
|
|
17
|
+
def get_broker(max_consumers=None):
|
|
18
|
+
return RabbitBroker(BrokerConnConfig.RABBITMQ_URL, max_consumers=max_consumers)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -35,9 +35,10 @@ from funboost.core.current_task import funboost_current_task, FctContext
|
|
|
35
35
|
from funboost.core.loggers import develop_logger
|
|
36
36
|
|
|
37
37
|
from funboost.core.func_params_model import BoosterParams, PublisherParams, BaseJsonAbleModel
|
|
38
|
+
from funboost.core.serialization import Serialization
|
|
38
39
|
from funboost.core.task_id_logger import TaskIdLogger
|
|
39
40
|
from funboost.constant import FunctionKind
|
|
40
|
-
|
|
41
|
+
|
|
41
42
|
from nb_libs.path_helper import PathHelper
|
|
42
43
|
from nb_log import (get_logger, LoggerLevelSetterMixin, LogManager, is_main_process,
|
|
43
44
|
nb_log_config_default)
|
|
@@ -139,7 +140,7 @@ class AbstractConsumer(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
139
140
|
if consumer_params.consuming_function is None:
|
|
140
141
|
raise ValueError('必须传 consuming_function 参数')
|
|
141
142
|
|
|
142
|
-
self._msg_schedule_time_intercal = 0 if consumer_params.qps
|
|
143
|
+
self._msg_schedule_time_intercal = 0 if consumer_params.qps in (None, 0) else 1.0 / consumer_params.qps
|
|
143
144
|
|
|
144
145
|
self._concurrent_mode_dispatcher = ConcurrentModeDispatcher(self)
|
|
145
146
|
if consumer_params.concurrent_mode == ConcurrentModeEnum.ASYNC:
|
|
@@ -232,6 +233,10 @@ class AbstractConsumer(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
232
233
|
self.logger.info(f'{self.queue_name} consumer 的消费者配置:\n {self.consumer_params.json_str_value()}')
|
|
233
234
|
atexit.register(self.join_shedual_task_thread)
|
|
234
235
|
|
|
236
|
+
if self.consumer_params.auto_start_consuming_message:
|
|
237
|
+
self.publisher_of_same_queue
|
|
238
|
+
self.start_consuming_message()
|
|
239
|
+
|
|
235
240
|
def _build_logger(self):
|
|
236
241
|
logger_prefix = self.consumer_params.logger_prefix
|
|
237
242
|
if logger_prefix != '':
|
|
@@ -408,8 +413,7 @@ class AbstractConsumer(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
408
413
|
extra_params = {'task_id': task_id, 'publish_time': round(time.time(), 4),
|
|
409
414
|
'publish_time_format': time.strftime('%Y-%m-%d %H:%M:%S')}
|
|
410
415
|
"""
|
|
411
|
-
|
|
412
|
-
msg = json.loads(msg)
|
|
416
|
+
msg = Serialization.to_dict(msg)
|
|
413
417
|
# 以下是清洗补全字段.
|
|
414
418
|
if 'extra' not in msg:
|
|
415
419
|
msg['extra'] = {'is_auto_fill_extra': True}
|
|
@@ -536,7 +540,7 @@ class AbstractConsumer(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
536
540
|
# print(999)
|
|
537
541
|
if self.consumer_params.is_show_message_get_from_broker:
|
|
538
542
|
# self.logger.debug(f'从 {broker_name} 中间件 的 {self._queue_name} 中取出的消息是 {msg}')
|
|
539
|
-
self.logger.debug(f'从 {broker_name or self.consumer_params.broker_kind} 中间件 的 {self._queue_name} 中取出的消息是 {
|
|
543
|
+
self.logger.debug(f'从 {broker_name or self.consumer_params.broker_kind} 中间件 的 {self._queue_name} 中取出的消息是 {Serialization.to_json_str(msg)}')
|
|
540
544
|
|
|
541
545
|
def _get_priority_conf(self, kw: dict, broker_task_config_key: str):
|
|
542
546
|
broker_task_config = kw['body'].get('extra', {}).get(broker_task_config_key, None)
|
|
@@ -585,10 +589,12 @@ class AbstractConsumer(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
585
589
|
# method_cls = getattr(sys.modules[self.consumer_params.consuming_function_class_module],
|
|
586
590
|
# self.consumer_params.consuming_function_class_name)
|
|
587
591
|
if self.publisher_params.consuming_function_kind == FunctionKind.CLASS_METHOD:
|
|
588
|
-
method_cls = getattr(PathHelper(method_first_param_value[ConstStrForClassMethod.
|
|
592
|
+
method_cls = getattr(PathHelper.import_module(method_first_param_value[ConstStrForClassMethod.CLS_MODULE]),
|
|
593
|
+
method_first_param_value[ConstStrForClassMethod.CLS_NAME])
|
|
589
594
|
real_function_only_params[method_first_param_name] = method_cls
|
|
590
595
|
elif self.publisher_params.consuming_function_kind == FunctionKind.INSTANCE_METHOD:
|
|
591
|
-
method_cls = getattr(PathHelper(method_first_param_value[ConstStrForClassMethod.
|
|
596
|
+
method_cls = getattr(PathHelper.import_module(method_first_param_value[ConstStrForClassMethod.CLS_MODULE]),
|
|
597
|
+
method_first_param_value[ConstStrForClassMethod.CLS_NAME])
|
|
592
598
|
obj = method_cls(**method_first_param_value[ConstStrForClassMethod.OBJ_INIT_PARAMS])
|
|
593
599
|
real_function_only_params[method_first_param_name] = obj
|
|
594
600
|
# print(real_function_only_params)
|
|
@@ -642,7 +648,7 @@ class AbstractConsumer(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
642
648
|
# RedisMixin().redis_db_frame.expire(kw['body']['extra']['task_id'], 600)
|
|
643
649
|
current_function_result_status.rpc_result_expire_seconds = self.consumer_params.rpc_result_expire_seconds
|
|
644
650
|
p.lpush(kw['body']['extra']['task_id'],
|
|
645
|
-
|
|
651
|
+
Serialization.to_json_str(current_function_result_status.get_status_dict(without_datetime_obj=True)))
|
|
646
652
|
p.expire(kw['body']['extra']['task_id'], self.consumer_params.rpc_result_expire_seconds)
|
|
647
653
|
p.execute()
|
|
648
654
|
|
|
@@ -812,7 +818,7 @@ class AbstractConsumer(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
812
818
|
with RedisMixin().redis_db_filter_and_rpc_result.pipeline() as p:
|
|
813
819
|
current_function_result_status.rpc_result_expire_seconds = self.consumer_params.rpc_result_expire_seconds
|
|
814
820
|
p.lpush(kw['body']['extra']['task_id'],
|
|
815
|
-
|
|
821
|
+
Serialization.to_json_str(current_function_result_status.get_status_dict(without_datetime_obj=True)))
|
|
816
822
|
p.expire(kw['body']['extra']['task_id'], self.consumer_params.rpc_result_expire_seconds)
|
|
817
823
|
p.execute()
|
|
818
824
|
|
|
@@ -852,7 +858,6 @@ class AbstractConsumer(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
852
858
|
fct = funboost_current_task()
|
|
853
859
|
fct.set_fct_context(None)
|
|
854
860
|
|
|
855
|
-
|
|
856
861
|
# noinspection PyProtectedMember
|
|
857
862
|
async def _async_run_consuming_function_with_confirm_and_retry(self, kw: dict, current_retry_times,
|
|
858
863
|
function_result_status: FunctionResultStatus, ):
|
|
@@ -1161,14 +1166,14 @@ class DistributedConsumerStatistics(RedisMixin, FunboostFileLoggerMixin):
|
|
|
1161
1166
|
results = self.redis_db_frame.smembers(redis_key)
|
|
1162
1167
|
with self.redis_db_frame.pipeline() as p:
|
|
1163
1168
|
for result in results:
|
|
1164
|
-
result_dict =
|
|
1169
|
+
result_dict = Serialization.to_dict(result)
|
|
1165
1170
|
if self.timestamp() - result_dict['hearbeat_timestamp'] > 15 \
|
|
1166
1171
|
or self._consumer_identification_map['consumer_uuid'] == result_dict['consumer_uuid']:
|
|
1167
1172
|
# 因为这个是10秒钟运行一次,15秒还没更新,那肯定是掉线了。如果消费者本身是自己也先删除。
|
|
1168
1173
|
p.srem(redis_key, result)
|
|
1169
1174
|
self._consumer_identification_map['hearbeat_datetime_str'] = time_util.DatetimeConverter().datetime_str
|
|
1170
1175
|
self._consumer_identification_map['hearbeat_timestamp'] = self.timestamp()
|
|
1171
|
-
value =
|
|
1176
|
+
value = Serialization.to_json_str(self._consumer_identification_map, )
|
|
1172
1177
|
p.sadd(redis_key, value)
|
|
1173
1178
|
p.execute()
|
|
1174
1179
|
|
|
@@ -5,7 +5,7 @@ import json
|
|
|
5
5
|
import time
|
|
6
6
|
from funboost.utils.redis_manager import RedisMixin
|
|
7
7
|
from funboost.utils import decorators
|
|
8
|
-
|
|
8
|
+
from funboost.core.serialization import Serialization
|
|
9
9
|
"""
|
|
10
10
|
此模块是依赖redis的确认消费,所以比较复杂。
|
|
11
11
|
"""
|
|
@@ -46,7 +46,7 @@ class ConsumerConfirmMixinWithTheHelpOfRedis(RedisMixin):
|
|
|
46
46
|
time_max = time.time() - self.UNCONFIRMED_TIMEOUT
|
|
47
47
|
for value in self.redis_db_frame.zrangebyscore(self._unack_zset_name, 0, time_max):
|
|
48
48
|
self.logger.warning(f'向 {self._queue_name} 重新放入未消费确认的任务 {value}')
|
|
49
|
-
self._requeue({'body':
|
|
49
|
+
self._requeue({'body': Serialization.to_dict(value)})
|
|
50
50
|
self.redis_db_frame.zrem(self._unack_zset_name, value)
|
|
51
51
|
self.logger.info(f'{self._unack_zset_name} 中有待确认消费任务的数量是'
|
|
52
52
|
f' {self.redis_db_frame.zcard(self._unack_zset_name)}')
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
import threading
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
from funboost import EmptyConsumer
|
|
7
|
+
from funboost.assist.faststream_helper import broker,app,get_broker
|
|
8
|
+
from faststream import FastStream,Context
|
|
9
|
+
from faststream.annotations import Logger
|
|
10
|
+
|
|
11
|
+
from funboost.concurrent_pool.async_helper import simple_run_in_executor
|
|
12
|
+
from funboost.core.helper_funs import delete_keys_and_return_new_dict
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class FastStreamConsumer(EmptyConsumer):
|
|
16
|
+
def custom_init(self):
|
|
17
|
+
self.broker = get_broker(max_consumers=self.consumer_params.concurrent_num)
|
|
18
|
+
subc = self.broker.subscriber(self.queue_name)
|
|
19
|
+
# @broker.subscriber(self.queue_name)
|
|
20
|
+
async def f(msg:str, logger: Logger,message=Context(),broker=Context(),context=Context(),):
|
|
21
|
+
self.logger.debug(f' 这条消息是 faststream 从 {self.queue_name} 队列中取出 ,是由 faststream 框架调度 {self.consuming_function.__name__} 函数处理,msg:{message} {context}')
|
|
22
|
+
# print(logger.name)
|
|
23
|
+
# return self.consuming_function(*args, **kwargs) # 如果没有声明 autoretry_for ,那么消费函数出错了就不会自动重试了。
|
|
24
|
+
# print(msg)
|
|
25
|
+
function_only_params = delete_keys_and_return_new_dict(json.loads(msg))
|
|
26
|
+
if self._consuming_function_is_asyncio:
|
|
27
|
+
result = await self.consuming_function(**function_only_params)
|
|
28
|
+
else:
|
|
29
|
+
result = await simple_run_in_executor(self.consuming_function,**function_only_params)
|
|
30
|
+
# print(result)
|
|
31
|
+
return result
|
|
32
|
+
subc(f)
|
|
33
|
+
self.faststream_subscriber = subc
|
|
34
|
+
|
|
35
|
+
def _shedual_task(self):
|
|
36
|
+
""" 完全由faststream框架接管控制消费,不使用funboost的AbstractConsumer的_run"""
|
|
37
|
+
while 1:
|
|
38
|
+
time.sleep(100)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _confirm_consume(self, kw):
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
def start_consuming_message(self):
|
|
45
|
+
def _f():
|
|
46
|
+
loop = asyncio.new_event_loop()
|
|
47
|
+
loop.run_until_complete(self.broker.connect())
|
|
48
|
+
loop.run_until_complete(self.faststream_subscriber.start())
|
|
49
|
+
loop.run_forever()
|
|
50
|
+
self.keep_circulating(10, block=False)(_f)()
|
|
51
|
+
# threading.Thread(target=_f).start()
|
|
52
|
+
|
|
53
|
+
def _requeue(self, kw):
|
|
54
|
+
pass
|
|
@@ -5,7 +5,7 @@ import json
|
|
|
5
5
|
from queue import Queue,SimpleQueue
|
|
6
6
|
from funboost.constant import BrokerEnum
|
|
7
7
|
from funboost.consumers.base_consumer import AbstractConsumer
|
|
8
|
-
from funboost.
|
|
8
|
+
from funboost.queues.memory_queues_map import PythonQueues
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class LocalPythonQueueConsumer(AbstractConsumer):
|
|
@@ -15,7 +15,7 @@ class LocalPythonQueueConsumer(AbstractConsumer):
|
|
|
15
15
|
|
|
16
16
|
@property
|
|
17
17
|
def local_python_queue(self) -> Queue:
|
|
18
|
-
return
|
|
18
|
+
return PythonQueues.get_queue(self._queue_name)
|
|
19
19
|
|
|
20
20
|
def _shedual_task(self):
|
|
21
21
|
while True:
|
|
@@ -10,7 +10,7 @@ import time
|
|
|
10
10
|
from funboost.constant import BrokerEnum
|
|
11
11
|
from funboost.consumers.base_consumer import AbstractConsumer
|
|
12
12
|
from funboost.utils.redis_manager import RedisMixin
|
|
13
|
-
|
|
13
|
+
from funboost.core.serialization import Serialization
|
|
14
14
|
|
|
15
15
|
class RedisConsumer(AbstractConsumer, RedisMixin):
|
|
16
16
|
"""
|
|
@@ -57,4 +57,4 @@ class RedisConsumer(AbstractConsumer, RedisMixin):
|
|
|
57
57
|
pass # redis没有确认消费的功能。
|
|
58
58
|
|
|
59
59
|
def _requeue(self, kw):
|
|
60
|
-
self.redis_db_frame.rpush(self._queue_name,
|
|
60
|
+
self.redis_db_frame.rpush(self._queue_name,Serialization.to_json_str(kw['body']))
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import json
|
|
5
5
|
import time
|
|
6
6
|
from funboost.consumers.base_consumer import AbstractConsumer
|
|
7
|
+
from funboost.core.serialization import Serialization
|
|
7
8
|
from funboost.utils.decorators import RedisDistributedLockContextManager
|
|
8
|
-
from funboost.utils.json_helper import JsonUtils
|
|
9
9
|
from funboost.utils.redis_manager import RedisMixin
|
|
10
10
|
|
|
11
11
|
|
|
@@ -40,7 +40,7 @@ class RedisConsumerAckUsingTimeout(AbstractConsumer, RedisMixin):
|
|
|
40
40
|
self.redis_db_frame.zrem(self._unack_zset_name, kw['task_str'])
|
|
41
41
|
|
|
42
42
|
def _requeue(self, kw):
|
|
43
|
-
self.redis_db_frame.rpush(self._queue_name,
|
|
43
|
+
self.redis_db_frame.rpush(self._queue_name, Serialization.to_json_str(kw['body']))
|
|
44
44
|
|
|
45
45
|
def _shedual_task(self):
|
|
46
46
|
lua = '''
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import json
|
|
5
5
|
from funboost.constant import BrokerEnum
|
|
6
6
|
from funboost.consumers.base_consumer import AbstractConsumer
|
|
7
|
+
from funboost.core.serialization import Serialization
|
|
7
8
|
from funboost.utils.redis_manager import RedisMixin
|
|
8
9
|
|
|
9
10
|
|
|
@@ -24,6 +25,6 @@ class RedisConsumer(AbstractConsumer, RedisMixin):
|
|
|
24
25
|
pass # redis没有确认消费的功能。
|
|
25
26
|
|
|
26
27
|
def _requeue(self, kw):
|
|
27
|
-
self.redis_db_frame.rpush(self._queue_name,
|
|
28
|
+
self.redis_db_frame.rpush(self._queue_name, Serialization.to_json_str(kw['body']))
|
|
28
29
|
|
|
29
30
|
|
|
@@ -11,6 +11,7 @@ import time
|
|
|
11
11
|
from collections import OrderedDict
|
|
12
12
|
import typing
|
|
13
13
|
|
|
14
|
+
from funboost.core.serialization import Serialization
|
|
14
15
|
from funboost.utils import decorators
|
|
15
16
|
from funboost.core.loggers import FunboostFileLoggerMixin
|
|
16
17
|
|
|
@@ -34,8 +35,7 @@ class RedisFilter(RedisMixin, FunboostFileLoggerMixin):
|
|
|
34
35
|
@staticmethod
|
|
35
36
|
def _get_ordered_str(value):
|
|
36
37
|
"""对json的键值对在redis中进行过滤,需要先把键值对排序,否则过滤会不准确如 {"a":1,"b":2} 和 {"b":2,"a":1}"""
|
|
37
|
-
|
|
38
|
-
value = json.loads(value)
|
|
38
|
+
value = Serialization.to_dict(value)
|
|
39
39
|
ordered_dict = OrderedDict()
|
|
40
40
|
for k in sorted(value):
|
|
41
41
|
ordered_dict[k] = value[k]
|
funboost/core/current_task.py
CHANGED
|
@@ -163,7 +163,7 @@ def get_current_taskid():
|
|
|
163
163
|
# return fct.function_result_status.task_id
|
|
164
164
|
try:
|
|
165
165
|
fct = funboost_current_task()
|
|
166
|
-
return fct.task_id # 不在funboost
|
|
166
|
+
return fct.task_id # 不在funboost的消费函数里面或者同个线程、协程就获取不到上下文了
|
|
167
167
|
except (AttributeError, LookupError) as e:
|
|
168
168
|
# print(e,type(e))
|
|
169
169
|
return 'no_task_id'
|
|
@@ -177,6 +177,7 @@ class BoosterParams(BaseJsonAbleModel):
|
|
|
177
177
|
do_not_run_by_specify_time: tuple = ('10:00:00', '22:00:00') # 不运行的时间段,在这个时间段自动不运行函数.
|
|
178
178
|
|
|
179
179
|
schedule_tasks_on_main_thread: bool = False # 直接在主线程调度任务,意味着不能直接在当前主线程同时开启两个消费者。
|
|
180
|
+
auto_start_consuming_message: bool = False # 是否在定义后就自动启动消费,无需用户手动写 .consume() 来启动消息消费。
|
|
180
181
|
|
|
181
182
|
consuming_function: typing.Callable = None # 消费函数,在@boost时候不用指定,因为装饰器知道下面的函数.
|
|
182
183
|
consuming_function_raw: typing.Callable = None
|
|
@@ -195,8 +196,7 @@ class BoosterParams(BaseJsonAbleModel):
|
|
|
195
196
|
|
|
196
197
|
auto_generate_info: dict = {} # 自动生成的信息,不需要用户主动传参.
|
|
197
198
|
|
|
198
|
-
consuming_function_kind
|
|
199
|
-
|
|
199
|
+
consuming_function_kind: typing.Optional[str] = None # 自动生成的信息,不需要用户主动传参,如果自动判断失误就传递。
|
|
200
200
|
|
|
201
201
|
@root_validator(skip_on_failure=True)
|
|
202
202
|
def check_values(cls, values: dict):
|
|
@@ -269,7 +269,6 @@ class PriorityConsumingControlConfig(BaseJsonAbleModel):
|
|
|
269
269
|
misfire_grace_time: typing.Union[int, None] = None
|
|
270
270
|
other_extra_params: dict = None # 其他参数, 例如消息优先级 , priority_control_config=PriorityConsumingControlConfig(other_extra_params={'priroty': priorityxx}),
|
|
271
271
|
|
|
272
|
-
|
|
273
272
|
@root_validator(skip_on_failure=True)
|
|
274
273
|
def cehck_values(cls, values: dict):
|
|
275
274
|
if values['countdown'] and values['eta']:
|
|
@@ -297,7 +296,6 @@ class PublisherParams(BaseJsonAbleModel):
|
|
|
297
296
|
consuming_function_kind: typing.Optional[str] = None # 自动生成的信息,不需要用户主动传参.
|
|
298
297
|
|
|
299
298
|
|
|
300
|
-
|
|
301
299
|
if __name__ == '__main__':
|
|
302
300
|
from funboost.concurrent_pool import FlexibleThreadPool
|
|
303
301
|
|
|
@@ -15,6 +15,7 @@ from pymongo import IndexModel, ReplaceOne
|
|
|
15
15
|
|
|
16
16
|
from funboost.core.func_params_model import FunctionResultStatusPersistanceConfig
|
|
17
17
|
from funboost.core.helper_funs import get_publish_time, delete_keys_and_return_new_dict
|
|
18
|
+
from funboost.core.serialization import Serialization
|
|
18
19
|
from funboost.utils import time_util, decorators
|
|
19
20
|
from funboost.utils.mongo_util import MongoMixin
|
|
20
21
|
# from nb_log import LoggerMixin
|
|
@@ -46,7 +47,7 @@ class FunctionResultStatus():
|
|
|
46
47
|
self.publish_time_str = time_util.DatetimeConverter(publish_time).datetime_str
|
|
47
48
|
function_params = delete_keys_and_return_new_dict(msg_dict, )
|
|
48
49
|
self.params = function_params
|
|
49
|
-
self.params_str =
|
|
50
|
+
self.params_str = Serialization.to_json_str(function_params)
|
|
50
51
|
self.result = None
|
|
51
52
|
self.run_times = 0
|
|
52
53
|
self.exception = None
|
|
@@ -78,7 +79,8 @@ class FunctionResultStatus():
|
|
|
78
79
|
# item.pop('time_start')
|
|
79
80
|
datetime_str = time_util.DatetimeConverter().datetime_str
|
|
80
81
|
try:
|
|
81
|
-
|
|
82
|
+
Serialization.to_json_str(item['result'])
|
|
83
|
+
# json.dumps(item['result']) # 不希望存不可json序列化的复杂类型。麻烦。存这种类型的结果是伪需求。
|
|
82
84
|
except TypeError:
|
|
83
85
|
item['result'] = str(item['result'])[:1000]
|
|
84
86
|
item.update({'insert_time_str': datetime_str,
|
|
@@ -98,7 +100,7 @@ class FunctionResultStatus():
|
|
|
98
100
|
return item
|
|
99
101
|
|
|
100
102
|
def __str__(self):
|
|
101
|
-
return f'''{self.__class__} {
|
|
103
|
+
return f'''{self.__class__} {Serialization.to_json_str(self.get_status_dict())}'''
|
|
102
104
|
|
|
103
105
|
|
|
104
106
|
class ResultPersistenceHelper(MongoMixin, FunboostFileLoggerMixin):
|
|
@@ -10,7 +10,7 @@ from funboost.concurrent_pool import CustomThreadPoolExecutor
|
|
|
10
10
|
from funboost.concurrent_pool.flexible_thread_pool import FlexibleThreadPoolMinWorkers0
|
|
11
11
|
from funboost.utils.redis_manager import RedisMixin
|
|
12
12
|
from funboost.utils.redis_manager import AioRedisMixin
|
|
13
|
-
|
|
13
|
+
from funboost.core.serialization import Serialization
|
|
14
14
|
|
|
15
15
|
class HasNotAsyncResult(Exception):
|
|
16
16
|
pass
|
|
@@ -42,7 +42,7 @@ class AsyncResult(RedisMixin):
|
|
|
42
42
|
self._has_pop = True
|
|
43
43
|
if redis_value is not None:
|
|
44
44
|
status_and_result_str = redis_value[1]
|
|
45
|
-
self._status_and_result =
|
|
45
|
+
self._status_and_result = Serialization.to_dict(status_and_result_str)
|
|
46
46
|
self.redis_db_filter_and_rpc_result.lpush(self.task_id, status_and_result_str)
|
|
47
47
|
self.redis_db_filter_and_rpc_result.expire(self.task_id, self._status_and_result['rpc_result_expire_seconds'])
|
|
48
48
|
return self._status_and_result
|
|
@@ -147,7 +147,7 @@ if __name__ == '__main__':
|
|
|
147
147
|
self._has_pop = True
|
|
148
148
|
if redis_value is not None:
|
|
149
149
|
status_and_result_str = redis_value[1]
|
|
150
|
-
self._status_and_result =
|
|
150
|
+
self._status_and_result = Serialization.to_dict(status_and_result_str)
|
|
151
151
|
await self.aioredis_db_filter_and_rpc_result.lpush(self.task_id, status_and_result_str)
|
|
152
152
|
await self.aioredis_db_filter_and_rpc_result.expire(self.task_id, self._status_and_result['rpc_result_expire_seconds'])
|
|
153
153
|
return self._status_and_result
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
import orjson
|
|
4
|
+
class Serialization:
|
|
5
|
+
@staticmethod
|
|
6
|
+
def to_json_str(dic:typing.Union[dict,str]):
|
|
7
|
+
if isinstance(dic,str):
|
|
8
|
+
return dic
|
|
9
|
+
str1 =orjson.dumps(dic)
|
|
10
|
+
return str1.decode('utf8')
|
|
11
|
+
|
|
12
|
+
@staticmethod
|
|
13
|
+
def to_dict(strx:typing.Union[str,dict]):
|
|
14
|
+
if isinstance(strx,dict):
|
|
15
|
+
return strx
|
|
16
|
+
return orjson.loads(strx)
|
|
@@ -16,9 +16,9 @@ from funboost.publishers.local_python_queue_publisher import LocalPythonQueuePub
|
|
|
16
16
|
from funboost.publishers.mongomq_publisher import MongoMqPublisher
|
|
17
17
|
|
|
18
18
|
from funboost.publishers.persist_queue_publisher import PersistQueuePublisher
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
from funboost.publishers.rabbitmq_pika_publisher import RabbitmqPublisher
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
from funboost.publishers.redis_publisher import RedisPublisher
|
|
23
23
|
from funboost.publishers.rocketmq_publisher import RocketmqPublisher
|
|
24
24
|
from funboost.publishers.redis_stream_publisher import RedisStreamPublisher
|
|
@@ -36,9 +36,8 @@ from funboost.consumers.nats_consumer import NatsConsumer
|
|
|
36
36
|
|
|
37
37
|
from funboost.consumers.peewee_conusmer import PeeweeConsumer
|
|
38
38
|
from funboost.consumers.persist_queue_consumer import PersistQueueConsumer
|
|
39
|
-
from funboost.consumers.rabbitmq_amqpstorm_consumer import RabbitmqConsumerAmqpStorm
|
|
40
39
|
from funboost.consumers.rabbitmq_pika_consumer import RabbitmqConsumer
|
|
41
|
-
|
|
40
|
+
|
|
42
41
|
from funboost.consumers.redis_brpoplpush_consumer import RedisBrpopLpushConsumer
|
|
43
42
|
from funboost.consumers.redis_consumer import RedisConsumer
|
|
44
43
|
from funboost.consumers.redis_consumer_ack_able import RedisConsumerAckAble
|
|
@@ -57,8 +56,8 @@ from funboost.consumers.base_consumer import AbstractConsumer
|
|
|
57
56
|
from funboost.constant import BrokerEnum
|
|
58
57
|
|
|
59
58
|
broker_kind__publsiher_consumer_type_map = {
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
|
|
60
|
+
|
|
62
61
|
BrokerEnum.REDIS: (RedisPublisher, RedisConsumer),
|
|
63
62
|
BrokerEnum.MEMORY_QUEUE: (LocalPythonQueuePublisher, LocalPythonQueueConsumer),
|
|
64
63
|
BrokerEnum.RABBITMQ_PIKA: (RabbitmqPublisher, RabbitmqConsumer),
|
|
@@ -111,6 +110,15 @@ def regist_to_funboost(broker_kind: str):
|
|
|
111
110
|
这样当用户需要使用某些三方包中间件作为消息队列时候,按照import报错信息,用户自己去pip安装好。或者 pip install funboost[all] 一次性安装所有中间件。
|
|
112
111
|
建议按照 https://github.com/ydf0509/funboost/blob/master/setup.py 中的 extra_brokers 和 install_requires 里面的版本号来安装三方包版本.
|
|
113
112
|
"""
|
|
113
|
+
if broker_kind == BrokerEnum.RABBITMQ_AMQPSTORM:
|
|
114
|
+
from funboost.publishers.rabbitmq_amqpstorm_publisher import RabbitmqPublisherUsingAmqpStorm
|
|
115
|
+
from funboost.consumers.rabbitmq_amqpstorm_consumer import RabbitmqConsumerAmqpStorm
|
|
116
|
+
register_custom_broker(BrokerEnum.RABBITMQ_AMQPSTORM, RabbitmqPublisherUsingAmqpStorm, RabbitmqConsumerAmqpStorm)
|
|
117
|
+
|
|
118
|
+
if broker_kind == BrokerEnum.RABBITMQ_RABBITPY:
|
|
119
|
+
from funboost.publishers.rabbitmq_rabbitpy_publisher import RabbitmqPublisherUsingRabbitpy
|
|
120
|
+
from funboost.consumers.rabbitmq_rabbitpy_consumer import RabbitmqConsumerRabbitpy
|
|
121
|
+
register_custom_broker(BrokerEnum.RABBITMQ_RABBITPY, RabbitmqPublisherUsingRabbitpy, RabbitmqConsumerRabbitpy)
|
|
114
122
|
|
|
115
123
|
if broker_kind == BrokerEnum.PULSAR:
|
|
116
124
|
from funboost.consumers.pulsar_consumer import PulsarConsumer
|
|
@@ -16,7 +16,7 @@ import time
|
|
|
16
16
|
import typing
|
|
17
17
|
from functools import wraps
|
|
18
18
|
from threading import Lock
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
|
|
21
21
|
import nb_log
|
|
22
22
|
from funboost.constant import ConstStrForClassMethod, FunctionKind
|
|
@@ -24,14 +24,16 @@ from funboost.core.func_params_model import PublisherParams, PriorityConsumingCo
|
|
|
24
24
|
from funboost.core.helper_funs import MsgGenerater
|
|
25
25
|
from funboost.core.loggers import develop_logger
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
|
|
29
29
|
# from nb_log import LoggerLevelSetterMixin, LoggerMixin
|
|
30
30
|
from funboost.core.loggers import LoggerLevelSetterMixin, FunboostFileLoggerMixin, get_logger
|
|
31
31
|
from funboost.core.msg_result_getter import AsyncResult, AioAsyncResult
|
|
32
|
+
from funboost.core.serialization import Serialization
|
|
32
33
|
from funboost.core.task_id_logger import TaskIdLogger
|
|
33
34
|
from funboost.utils import decorators
|
|
34
35
|
from funboost.funboost_config_deafult import BrokerConnConfig, FunboostCommonConfig
|
|
36
|
+
from nb_libs.path_helper import PathHelper
|
|
35
37
|
|
|
36
38
|
RedisAsyncResult = AsyncResult # 别名
|
|
37
39
|
RedisAioAsyncResult = AioAsyncResult # 别名
|
|
@@ -179,13 +181,13 @@ class AbstractPublisher(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
179
181
|
|
|
180
182
|
@staticmethod
|
|
181
183
|
def _get_from_other_extra_params(k: str, msg):
|
|
182
|
-
msg_dict = json.loads(msg) if isinstance(msg, str) else msg
|
|
184
|
+
# msg_dict = json.loads(msg) if isinstance(msg, str) else msg
|
|
185
|
+
msg_dict = Serialization.to_dict(msg)
|
|
183
186
|
return msg_dict['extra'].get('other_extra_params', {}).get(k, None)
|
|
184
187
|
|
|
185
188
|
def _convert_msg(self, msg: typing.Union[str, dict], task_id=None,
|
|
186
|
-
priority_control_config: PriorityConsumingControlConfig = None) -> (typing.Dict, typing.Dict, typing.Dict):
|
|
187
|
-
|
|
188
|
-
msg = json.loads(msg)
|
|
189
|
+
priority_control_config: PriorityConsumingControlConfig = None) -> (typing.Dict, typing.Dict, typing.Dict,str):
|
|
190
|
+
msg = Serialization.to_dict(msg)
|
|
189
191
|
msg_function_kw = copy.deepcopy(msg)
|
|
190
192
|
raw_extra = {}
|
|
191
193
|
if 'extra' in msg:
|
|
@@ -214,7 +216,7 @@ class AbstractPublisher(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
214
216
|
msg, msg_function_kw, extra_params, task_id = self._convert_msg(msg, task_id, priority_control_config)
|
|
215
217
|
t_start = time.time()
|
|
216
218
|
decorators.handle_exception(retry_times=10, is_throw_error=True, time_sleep=0.1)(
|
|
217
|
-
self.concrete_realization_of_publish)(
|
|
219
|
+
self.concrete_realization_of_publish)(Serialization.to_json_str(msg))
|
|
218
220
|
|
|
219
221
|
self.logger.debug(f'向{self._queue_name} 队列,推送消息 耗时{round(time.time() - t_start, 4)}秒 {msg_function_kw}', extra={'task_id': task_id}) # 显示msg太长了。
|
|
220
222
|
with self._lock_for_count:
|
|
@@ -228,10 +230,16 @@ class AbstractPublisher(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
228
230
|
|
|
229
231
|
def send_msg(self, msg: typing.Union[dict, str]):
|
|
230
232
|
"""直接发送任意消息内容到消息队列,不生成辅助参数,无视函数入参名字,不校验入参个数和键名"""
|
|
231
|
-
if isinstance(msg, dict):
|
|
232
|
-
msg = json.dumps(msg, ensure_ascii=False)
|
|
233
233
|
decorators.handle_exception(retry_times=10, is_throw_error=True, time_sleep=0.1)(
|
|
234
|
-
self.concrete_realization_of_publish)(msg)
|
|
234
|
+
self.concrete_realization_of_publish)(Serialization.to_json_str(msg))
|
|
235
|
+
|
|
236
|
+
@staticmethod
|
|
237
|
+
def __get_cls_file(cls: type):
|
|
238
|
+
if cls.__module__ == '__main__':
|
|
239
|
+
cls_file = Path(sys.argv[0]).resolve().as_posix()
|
|
240
|
+
else:
|
|
241
|
+
cls_file = Path(sys.modules[cls.__module__].__file__).resolve().as_posix()
|
|
242
|
+
return cls_file
|
|
235
243
|
|
|
236
244
|
def push(self, *func_args, **func_kwargs):
|
|
237
245
|
"""
|
|
@@ -260,9 +268,11 @@ class AbstractPublisher(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
260
268
|
# )
|
|
261
269
|
cls = func_args_list[0]
|
|
262
270
|
# print(cls,cls.__name__, sys.modules[cls.__module__].__file__)
|
|
271
|
+
|
|
263
272
|
func_args_list[0] = {ConstStrForClassMethod.FIRST_PARAM_NAME: self.publish_params_checker.all_arg_name[0],
|
|
264
273
|
ConstStrForClassMethod.CLS_NAME: cls.__name__,
|
|
265
|
-
ConstStrForClassMethod.CLS_FILE:
|
|
274
|
+
ConstStrForClassMethod.CLS_FILE: self.__get_cls_file(cls),
|
|
275
|
+
ConstStrForClassMethod.CLS_MODULE: PathHelper(self.__get_cls_file(cls)).get_module_name(),
|
|
266
276
|
}
|
|
267
277
|
elif self.publisher_params.consuming_function_kind == FunctionKind.INSTANCE_METHOD:
|
|
268
278
|
obj = func_args[0]
|
|
@@ -271,7 +281,8 @@ class AbstractPublisher(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
|
271
281
|
raise ValueError(f'消费函数 {self.publisher_params.consuming_function} 是实例方法,实例必须有 {ConstStrForClassMethod.OBJ_INIT_PARAMS} 属性')
|
|
272
282
|
func_args_list[0] = {ConstStrForClassMethod.FIRST_PARAM_NAME: self.publish_params_checker.all_arg_name[0],
|
|
273
283
|
ConstStrForClassMethod.CLS_NAME: cls.__name__,
|
|
274
|
-
ConstStrForClassMethod.CLS_FILE:
|
|
284
|
+
ConstStrForClassMethod.CLS_FILE: self.__get_cls_file(cls),
|
|
285
|
+
ConstStrForClassMethod.CLS_MODULE: PathHelper(self.__get_cls_file(cls)).get_module_name(),
|
|
275
286
|
ConstStrForClassMethod.OBJ_INIT_PARAMS: getattr(obj, ConstStrForClassMethod.OBJ_INIT_PARAMS),
|
|
276
287
|
|
|
277
288
|
}
|
|
@@ -330,11 +341,14 @@ def deco_mq_conn_error(f):
|
|
|
330
341
|
# noinspection PyBroadException
|
|
331
342
|
try:
|
|
332
343
|
return f(self, *args, **kwargs)
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
344
|
+
except Exception as e:
|
|
345
|
+
import amqpstorm
|
|
346
|
+
from pikav1.exceptions import AMQPError as PikaAMQPError
|
|
347
|
+
if isinstance(e,(PikaAMQPError, amqpstorm.AMQPError)):
|
|
348
|
+
# except (PikaAMQPError, amqpstorm.AMQPError,) as e: # except BaseException as e: # 现在装饰器用到了绝大多出地方,单个异常类型不行。ex
|
|
349
|
+
self.logger.error(f'中间件链接出错 ,方法 {f.__name__} 出错 ,{e}')
|
|
350
|
+
self.init_broker()
|
|
351
|
+
return f(self, *args, **kwargs)
|
|
338
352
|
except BaseException as e:
|
|
339
353
|
self.logger.critical(e, exc_info=True)
|
|
340
354
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# @Author : ydf
|
|
3
|
+
# @Time : 2023/8/8 0008 12:12
|
|
4
|
+
|
|
5
|
+
import abc
|
|
6
|
+
import asyncio
|
|
7
|
+
import json
|
|
8
|
+
import time
|
|
9
|
+
import typing
|
|
10
|
+
|
|
11
|
+
from funboost import PriorityConsumingControlConfig
|
|
12
|
+
from funboost.core.serialization import Serialization
|
|
13
|
+
from funboost.publishers.base_publisher import AbstractPublisher
|
|
14
|
+
from funboost.assist.faststream_helper import app,get_broker
|
|
15
|
+
from faststream import FastStream,Context
|
|
16
|
+
from faststream.annotations import Logger
|
|
17
|
+
|
|
18
|
+
class FastStreamPublisher(AbstractPublisher, metaclass=abc.ABCMeta):
|
|
19
|
+
"""
|
|
20
|
+
空的发布者,空的实现,需要搭配 boost入参的 consumer_override_cls 和 publisher_override_cls使用,或者被继承。
|
|
21
|
+
"""
|
|
22
|
+
def custom_init(self):
|
|
23
|
+
pass
|
|
24
|
+
# asyncio.get_event_loop().run_until_complete(broker.start())
|
|
25
|
+
self.broker = get_broker()
|
|
26
|
+
asyncio.get_event_loop().run_until_complete(self.broker.connect())
|
|
27
|
+
|
|
28
|
+
def publish(self, msg: typing.Union[str, dict], task_id=None,
|
|
29
|
+
priority_control_config: PriorityConsumingControlConfig = None) :
|
|
30
|
+
msg, msg_function_kw, extra_params, task_id = self._convert_msg(msg, task_id, priority_control_config)
|
|
31
|
+
t_start = time.time()
|
|
32
|
+
faststream_result = asyncio.get_event_loop().run_until_complete(self.broker.publish(Serialization.to_json_str(msg), self.queue_name))
|
|
33
|
+
self.logger.debug(f'向{self._queue_name} 队列,推送消息 耗时{round(time.time() - t_start, 4)}秒 {msg_function_kw}') # 显示msg太长了。
|
|
34
|
+
with self._lock_for_count:
|
|
35
|
+
self.count_per_minute += 1
|
|
36
|
+
self.publish_msg_num_total += 1
|
|
37
|
+
if time.time() - self._current_time > 10:
|
|
38
|
+
self.logger.info(
|
|
39
|
+
f'10秒内推送了 {self.count_per_minute} 条消息,累计推送了 {self.publish_msg_num_total} 条消息到 {self._queue_name} 队列中')
|
|
40
|
+
self._init_count()
|
|
41
|
+
# return AsyncResult(task_id)
|
|
42
|
+
return faststream_result #
|
|
43
|
+
|
|
44
|
+
def concrete_realization_of_publish(self, msg):
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def clear(self):
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def get_message_count(self):
|
|
53
|
+
return -1
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def close(self):
|
|
57
|
+
pass
|
|
@@ -5,6 +5,7 @@ from collections import deque
|
|
|
5
5
|
from queue import Queue, SimpleQueue
|
|
6
6
|
|
|
7
7
|
from funboost.publishers.base_publisher import AbstractPublisher
|
|
8
|
+
from funboost.queues.memory_queues_map import PythonQueues
|
|
8
9
|
|
|
9
10
|
local_pyhton_queue_name__local_pyhton_queue_obj_map = dict() # 使local queue和其他中间件完全一样的使用方式,使用映射保存队列的名字,使消费和发布通过队列名字能找到队列对象。
|
|
10
11
|
|
|
@@ -15,22 +16,23 @@ class LocalPythonQueuePublisher(AbstractPublisher):
|
|
|
15
16
|
"""
|
|
16
17
|
|
|
17
18
|
# noinspection PyAttributeOutsideInit
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def local_python_queue(self) -> Queue:
|
|
22
|
+
return PythonQueues.get_queue(self._queue_name)
|
|
22
23
|
|
|
23
24
|
def concrete_realization_of_publish(self, msg):
|
|
24
25
|
# noinspection PyTypeChecker
|
|
25
|
-
|
|
26
|
+
pass
|
|
27
|
+
self.local_python_queue.put(msg)
|
|
26
28
|
|
|
27
29
|
def clear(self):
|
|
28
30
|
# noinspection PyUnresolvedReferences
|
|
29
|
-
self.
|
|
31
|
+
self.local_python_queue.queue.clear()
|
|
30
32
|
self.logger.warning(f'清除 本地队列中的消息成功')
|
|
31
33
|
|
|
32
34
|
def get_message_count(self):
|
|
33
|
-
return self.
|
|
35
|
+
return self.local_python_queue.qsize()
|
|
34
36
|
|
|
35
37
|
def close(self):
|
|
36
38
|
pass
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import queue
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class PythonQueues:
|
|
5
|
+
local_pyhton_queue_name__local_pyhton_queue_obj_map = {}
|
|
6
|
+
|
|
7
|
+
@classmethod
|
|
8
|
+
def get_queue(cls,queue_name):
|
|
9
|
+
if queue_name not in cls.local_pyhton_queue_name__local_pyhton_queue_obj_map:
|
|
10
|
+
cls.local_pyhton_queue_name__local_pyhton_queue_obj_map[queue_name] = queue.Queue()
|
|
11
|
+
return cls.local_pyhton_queue_name__local_pyhton_queue_obj_map[queue_name]
|
funboost/utils/json_helper.py
CHANGED
|
@@ -45,20 +45,20 @@ def monkey_patch_json():
|
|
|
45
45
|
json.dumps = _dumps
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
class JsonUtils:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
48
|
+
# class JsonUtils:
|
|
49
|
+
# @staticmethod
|
|
50
|
+
# def to_dict(obj:typing.Union[str,dict,list]):
|
|
51
|
+
# if isinstance(obj,str):
|
|
52
|
+
# return json.loads(obj)
|
|
53
|
+
# else:
|
|
54
|
+
# return obj
|
|
55
|
+
#
|
|
56
|
+
# @staticmethod
|
|
57
|
+
# def to_json_str(obj:typing.Union[str,dict,list]):
|
|
58
|
+
# if isinstance(obj,str):
|
|
59
|
+
# return obj
|
|
60
|
+
# else:
|
|
61
|
+
# return json.dumps(obj,ensure_ascii=False)
|
|
62
62
|
|
|
63
63
|
if __name__ == '__main__':
|
|
64
64
|
pass
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: funboost
|
|
3
|
-
Version: 45.
|
|
3
|
+
Version: 45.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
|
|
@@ -27,7 +27,7 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
License-File: LICENSE
|
|
29
29
|
Requires-Dist: nb-log (>=12.6)
|
|
30
|
-
Requires-Dist: nb-libs (>=1.
|
|
30
|
+
Requires-Dist: nb-libs (>=1.8)
|
|
31
31
|
Requires-Dist: nb-time (>=1.8)
|
|
32
32
|
Requires-Dist: pymongo (==4.3.3)
|
|
33
33
|
Requires-Dist: AMQPStorm (==2.10.6)
|
|
@@ -52,6 +52,7 @@ Requires-Dist: auto-run-on-remote
|
|
|
52
52
|
Requires-Dist: frozenlist
|
|
53
53
|
Requires-Dist: fire
|
|
54
54
|
Requires-Dist: pydantic
|
|
55
|
+
Requires-Dist: orjson
|
|
55
56
|
Provides-Extra: all
|
|
56
57
|
Requires-Dist: confluent-kafka (==1.7.0) ; extra == 'all'
|
|
57
58
|
Requires-Dist: celery ; extra == 'all'
|
|
@@ -131,16 +132,25 @@ Requires-Dist: flask-login ; extra == 'flask'
|
|
|
131
132
|
|
|
132
133
|
|
|
133
134
|
<pre style="color: greenyellow;background-color: #0c1119; font-size: medium;">
|
|
134
|
-
pip install funboost ,python
|
|
135
|
-
|
|
135
|
+
pip install funboost ,python全功能分布式函数调度框架。 demo用法例子见文档1.3
|
|
136
|
+
|
|
137
|
+
只需要一行@boost代码即可分布式执行python一切任意函数,99%用过funboost的pythoner 感受是 方便 快速 强大。
|
|
138
|
+
支持python所有类型的并发模式,消息队列方面支持全球一切知名消息队列中间件和模拟的实现消息队列,
|
|
136
139
|
同时funboost支持celery整个框架作为核心来发布和消费消息,使用funboost的极简api方式来自动化配置和利用celery调度,
|
|
137
140
|
也支持huey dramatiq rq等任务队列框架作为funboost的broker。
|
|
141
|
+
|
|
138
142
|
python函数加速器,框架包罗万象,一统编程思维,兼容50% python编程业务场景,适用范围广。
|
|
139
|
-
只需要一行代码即可分布式执行python一切函数,99%用过funboost的pythoner 感受是 方便 快速 强大。
|
|
140
143
|
python万能分布式函数调度框架,支持5种并发模式,30+种消息队列中间件(或任务队列框架),
|
|
141
144
|
30种任务控制功能。给任意python函数赋能。
|
|
142
145
|
用途概念就是常规经典的 生产者 + 消息队列中间件 + 消费者 编程思想。
|
|
146
|
+
|
|
143
147
|
框架只需要学习@boost这一个装饰器的入参就可以,所有用法几乎和1.3例子一摸一样,非常简化简单。
|
|
148
|
+
框架对代码没有入侵,可以加到任意已有项目而对项目python文件目录结构0要求,
|
|
149
|
+
不像 celery django scrapy 这样的框架,要从一开始就开始规划好项目目录结构,如果不想用框架了,
|
|
150
|
+
或者想改变使用其他框架框架,那么已经所写的代码组织形式就几乎成了废物,需要大改特改.
|
|
151
|
+
但是funboost完全不会这样,加上或去掉@boost装饰器,对你的项目影响为0,用户照常使用,
|
|
152
|
+
所以用户可以对任意项目,任意时候,引入使用funboost或者去掉使用funboost,代码组织形式不需要发生变化.
|
|
153
|
+
|
|
144
154
|
</pre>
|
|
145
155
|
|
|
146
156
|
### 框架评价
|
|
@@ -157,6 +167,7 @@ python万能分布式函数调度框架,支持5种并发模式,30+种消息
|
|
|
157
167
|
,连celery命令行运行起来都要反复猜测尝试。
|
|
158
168
|
正因为如此用户从心理已近十分惧怕学习一种叫python框架的东西了,用户顶多愿意学习一个python包或者模块,
|
|
159
169
|
学习一个框架会非常害怕觉得难度高且耗时,所以非常反感尝试新的框架。
|
|
170
|
+
用过的99%都说funboost比celery简单方便太多,看都不看的人第一秒就是开始质疑重复造轮子.
|
|
160
171
|
|
|
161
172
|
funboost只有一个@boost装饰器,@boost入参能自动补全,更重要的是被@boost装饰的函数,
|
|
162
173
|
有哪些方法,每个方法入参是什么都能自动补全。funboost的中间件配置文件自当生成在用户当前项目根目录,
|
|
@@ -295,10 +306,10 @@ if __name__ == '__main__':
|
|
|
295
306
|
2)funboost 使用内存队列,设置10线程并发
|
|
296
307
|
```python
|
|
297
308
|
import time
|
|
298
|
-
from funboost import
|
|
309
|
+
from funboost import BoosterParams, BrokerEnum
|
|
299
310
|
|
|
300
311
|
|
|
301
|
-
@
|
|
312
|
+
@BoosterParams(queue_name="test_insteda_thread_queue", broker_kind=BrokerEnum.MEMORY_QUEUE, concurrent_num=10, auto_start_consuming_message=True)
|
|
302
313
|
def f(x):
|
|
303
314
|
time.sleep(3)
|
|
304
315
|
print(x)
|
|
@@ -307,7 +318,8 @@ def f(x):
|
|
|
307
318
|
if __name__ == '__main__':
|
|
308
319
|
for i in range(100):
|
|
309
320
|
f.push(i)
|
|
310
|
-
|
|
321
|
+
|
|
322
|
+
|
|
311
323
|
```
|
|
312
324
|
|
|
313
325
|
|
|
@@ -562,7 +574,7 @@ python比其他语言更需要分布式函数调度框架来执行函数,有
|
|
|
562
574
|
funboost通过支持celery作为broker_kind,使celer框架变成了funboost的一个子集
|
|
563
575
|
```
|
|
564
576
|
|
|
565
|
-
[查看分布式函数调度框架完整文档](https://funboost.readthedocs.io/
|
|
577
|
+
[查看分布式函数调度框架完整文档](https://funboost.readthedocs.io/)
|
|
566
578
|
|
|
567
579
|
|
|
568
580
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
funboost/__init__.py,sha256=
|
|
1
|
+
funboost/__init__.py,sha256=Gj0PweyuIxvJ8aa7Ai5WF0eFUdP06133pA_MQ7VLY5M,3956
|
|
2
2
|
funboost/__init__old.py,sha256=9Kv3cPLnPkbzMRnuJFVkPsuDdx1CdcSIuITkpdncZSc,20382
|
|
3
3
|
funboost/__main__.py,sha256=-6Nogi666Y0LN8fVm3JmHGTOk8xEGWvotW_GDbSaZME,1065
|
|
4
4
|
funboost/constant.py,sha256=STzRDZbuCC5FFV-uD_0r2beGsD1Zni4kregzR11z3Ok,8148
|
|
@@ -7,10 +7,12 @@ funboost/set_frame_config.py,sha256=kxYo_x2pMihwfTgFWrLxNbgI0IbFYC_HpSd9YLQM1ig,
|
|
|
7
7
|
funboost/assist/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
funboost/assist/celery_helper.py,sha256=EOxsl-y65JPwHrmL0LTGAj1nKLbS0qyRbuXcJ0xo9wc,5721
|
|
9
9
|
funboost/assist/dramatiq_helper.py,sha256=9mUyfBMAJXzwvB8LwOmapn3rY30a6UXt3tNOfL6OXoM,2106
|
|
10
|
+
funboost/assist/faststream_helper.py,sha256=BmBaFsvsjQK2SO71ulHRsEwO28uYZm2uMMvXkHzLi1E,631
|
|
10
11
|
funboost/assist/huey_helper.py,sha256=PuJHIzK5oRd5RzbuxLMHhWlkKO3J-ObRK0mrMs_iQWs,1770
|
|
11
12
|
funboost/assist/rocketry_helper.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
13
|
funboost/assist/rq_helper.py,sha256=HYvQ7VqIMx7dAVZZhtqQmGReCJavEuc1BQPYvfm1EvY,1549
|
|
13
14
|
funboost/assist/rq_windows_worker.py,sha256=jQlGmU0FWPVoKVP8cyuwTuAca9VfSd75F5Qw_hR04y0,4831
|
|
15
|
+
funboost/assist/taskiq_helper.py,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
14
16
|
funboost/beggar_version_implementation/beggar_redis_consumer.py,sha256=x5cH6Vc3_UooY2oPeC9MlpMewrGd9qXCx6gEWi1fGa0,3941
|
|
15
17
|
funboost/concurrent_pool/__init__.py,sha256=C27xYXj7c1NGuVeG7K2LxKH7JKnGwfPfITyon6xFaoE,803
|
|
16
18
|
funboost/concurrent_pool/async_helper.py,sha256=bK4SyTu_WpgxCvai2AaiI7EKQ-COiDbqu0WPnbaJ1jM,3421
|
|
@@ -33,11 +35,12 @@ funboost/concurrent_pool/backup/async_pool_executor0223.py,sha256=RVUZiylUvpTm6U
|
|
|
33
35
|
funboost/concurrent_pool/backup/async_pool_executor_back.py,sha256=KL6zEQaa1KkZOlAO85mCC1gwLm-YC5Ghn21IUom0UKM,9598
|
|
34
36
|
funboost/concurrent_pool/backup/async_pool_executor_janus.py,sha256=OHMWJ9l3EYTpPpcrPrGGKd4K0tmQ2PN8HiX0Dta0EOo,5728
|
|
35
37
|
funboost/consumers/__init__.py,sha256=ZXY_6Kut1VYNQiF5aWEgIWobsW1ht9YUP0TdRZRWFqI,126
|
|
36
|
-
funboost/consumers/base_consumer.py,sha256=
|
|
38
|
+
funboost/consumers/base_consumer.py,sha256=prs8RnEHpNC_xh-3Uan3Xhcr4zyYqgFOl-5N4W8SHG8,80342
|
|
37
39
|
funboost/consumers/celery_consumer.py,sha256=9gtz7nlZkmv3ErmaseT0_Q__ltSPx-fOcwi-TMPoaLA,9220
|
|
38
|
-
funboost/consumers/confirm_mixin.py,sha256=
|
|
40
|
+
funboost/consumers/confirm_mixin.py,sha256=NPOhxYF0nmJR5J03nXD6ndLo33eAUI60PXvk3WFyoz0,6126
|
|
39
41
|
funboost/consumers/dramatiq_consumer.py,sha256=ozmeAfeF0U-YNYHK4suQB0N264h5AZdfMH0O45Mh-8A,2229
|
|
40
42
|
funboost/consumers/empty_consumer.py,sha256=pU5py60l-JDQFTJlaMpfuFyzRGqDUnOrpKhG9gOg39A,759
|
|
43
|
+
funboost/consumers/faststream_consumer.py,sha256=3xzq5fwzAcmhavdh06lLK-Wrjvm4woJIJYkUG3K8w9c,2295
|
|
41
44
|
funboost/consumers/http_consumer.py,sha256=2MVqEzHW9qIKWvgIQS7VncGfvpmWhQ3BWWjfyHWC-as,2179
|
|
42
45
|
funboost/consumers/http_consumer000.py,sha256=PiiSLSQB-hHgS1vAn8DoHD2siC3zO6_kKjVW0g6AFIc,4379
|
|
43
46
|
funboost/consumers/httpsqs_consumer.py,sha256=kaqOcrKMLrSR27XqeiheRDmpF1KDVDghgbHcefTjqt8,1171
|
|
@@ -45,7 +48,7 @@ funboost/consumers/huey_consumer.py,sha256=cW10ZPxdZQzUuJwdqQpJIRPTj2vCbZS0uXFJ7
|
|
|
45
48
|
funboost/consumers/kafka_consumer.py,sha256=OAq6fclhDBufsWTowAikGBYjptc28SIE-EDzFEz9J-I,4324
|
|
46
49
|
funboost/consumers/kafka_consumer_manually_commit.py,sha256=kkHyTf4EQFEEoyiZ-pZQBR-g3M1rkFYnfKFXoeODCIE,9620
|
|
47
50
|
funboost/consumers/kombu_consumer.py,sha256=hj2J-1r5hBbcTNXIpU6qe1MwYPD-8gEKlDTSRV3B5Js,10208
|
|
48
|
-
funboost/consumers/local_python_queue_consumer.py,sha256=
|
|
51
|
+
funboost/consumers/local_python_queue_consumer.py,sha256=4Cel1WaNwbRpDux22USP8is5R9__A_-LlqyHjcw02Z4,1160
|
|
49
52
|
funboost/consumers/memory_deque_consumer.py,sha256=tTwOkrB9GdySOQstVLnU4hnBnap6rafCeoXhmV0TI5c,1110
|
|
50
53
|
funboost/consumers/mongomq_consumer.py,sha256=e1Cupe-Cb2LUuJlQhER6NecrvK7FyzKKZ2HxyfOI-OY,1119
|
|
51
54
|
funboost/consumers/mqtt_consumer.py,sha256=iLWKxe0CjKHUYrE6YMWNJHto0tD3siUAvZl9ssNsz_s,2297
|
|
@@ -60,12 +63,12 @@ funboost/consumers/rabbitmq_pika_consumer.py,sha256=51IkRUSR0v2v7BUlA8oInx81VGeO
|
|
|
60
63
|
funboost/consumers/rabbitmq_pika_consumerv0.py,sha256=rIQToBTBqGdjnzMhg0vyZMY87NtK_Uw8ggiTu39JQ_w,4777
|
|
61
64
|
funboost/consumers/rabbitmq_rabbitpy_consumer.py,sha256=xxINY037pmgF3_lJA-zhf9qUIUx6DdqC7tsUOQL3dL4,1330
|
|
62
65
|
funboost/consumers/redis_brpoplpush_consumer.py,sha256=HqjgjjEibq7D-5XFpJtyaPvtfXD5zbq9cjSHx4aM1gU,2952
|
|
63
|
-
funboost/consumers/redis_consumer.py,sha256=
|
|
66
|
+
funboost/consumers/redis_consumer.py,sha256=RdxJvWWQvQdjXWWdUebmgB7KRDWQBeF87Q9kd_DeUZk,2735
|
|
64
67
|
funboost/consumers/redis_consumer_ack_able.py,sha256=7zP9BQNfONLBbYJFjgNtIPVqbHwklAdcPUIA8Y7M8go,7411
|
|
65
|
-
funboost/consumers/redis_consumer_ack_using_timeout.py,sha256=
|
|
68
|
+
funboost/consumers/redis_consumer_ack_using_timeout.py,sha256=XW3zUSqmS0xDR-eMN7ds7p2ThtOgS8qUDZ9fui4_z9o,4213
|
|
66
69
|
funboost/consumers/redis_consumer_priority.py,sha256=C-ftnlGPPoB7YV3GvwLu9POVGDn_GKlBqO6NlsZ-hdY,5566
|
|
67
|
-
funboost/consumers/redis_consumer_simple.py,sha256=
|
|
68
|
-
funboost/consumers/redis_filter.py,sha256=
|
|
70
|
+
funboost/consumers/redis_consumer_simple.py,sha256=trPrMHSVU1Y_fY-xz5tFFmt1zjV-9_joPYRHqvyZnL8,874
|
|
71
|
+
funboost/consumers/redis_filter.py,sha256=UlkTQSZQSwb98nqkAHkrEKVri_XxHF0T7HmpghZ597s,7316
|
|
69
72
|
funboost/consumers/redis_pubsub_consumer.py,sha256=8V8EqobKpEXzpsQx_H3A-JBKLsWOsE0n16g62tUMMYY,1122
|
|
70
73
|
funboost/consumers/redis_stream_consumer.py,sha256=LVQa19MDfSlC8SYSYFPwJnJi62UIzfPHAbBVysLmNw8,6538
|
|
71
74
|
funboost/consumers/rocketmq_consumer.py,sha256=23KLRz8iO9e_x7asrceRJYhwJFMruUgmKw7m3pHVkw0,1692
|
|
@@ -84,27 +87,28 @@ funboost/contrib/save_result_status_to_sqldb.py,sha256=AxvD7nHs4sjr9U0kwEZzyPKrs
|
|
|
84
87
|
funboost/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
85
88
|
funboost/core/active_cousumer_info_getter.py,sha256=09fEc-BTEIRfDDfHmOvKnMjLjtOyp4edLsUlAXUR_Qs,4966
|
|
86
89
|
funboost/core/booster.py,sha256=vztzE7KqfXsg_LODmW5cX1M8as6n2tPdqEjkOLa7SYM,18276
|
|
87
|
-
funboost/core/current_task.py,sha256=
|
|
90
|
+
funboost/core/current_task.py,sha256=Oils18_vAqGvV4pqM6yYwnhMaFn3nrpzo1PO48HHidQ,5799
|
|
88
91
|
funboost/core/exceptions.py,sha256=pLF7BkRJAfDiWp2_xGZqencmwdPiSQI1NENbImExknY,1311
|
|
89
92
|
funboost/core/fabric_deploy_helper.py,sha256=foieeqlNySuU9axJzNF6TavPjIUSYBx9UO3syVKUiyY,9999
|
|
90
93
|
funboost/core/funboost_config_getter.py,sha256=TDccp5pQamkoJXkwyPwGsQGDJY8ej8ZT8L8RESSAD2w,382
|
|
91
94
|
funboost/core/funboost_time.py,sha256=IbB4dFCpg3oGUe90ssAJ_x0eDPtAVfvsUr4esdoKaOk,1777
|
|
92
|
-
funboost/core/func_params_model.py,sha256=
|
|
95
|
+
funboost/core/func_params_model.py,sha256=5cFPTPZxtnp9wOx7aie4fjEQv4u63tS7M8-UrokBupE,20776
|
|
93
96
|
funboost/core/function_result_status_config.py,sha256=PyjqAQOiwsLt28sRtH-eYRjiI3edPFO4Nde0ILFRReE,1764
|
|
94
|
-
funboost/core/function_result_status_saver.py,sha256=
|
|
97
|
+
funboost/core/function_result_status_saver.py,sha256=yHKZF9MjmhI-Q4Mkrka7DdweJ0wpgfLmgfAlsfkCeCk,9274
|
|
95
98
|
funboost/core/helper_funs.py,sha256=Jzy6t4-cugI-tOztgt7DGSos3tkxk2R4IOUOK2OWJ-I,2365
|
|
96
99
|
funboost/core/kill_remote_task.py,sha256=MZ5vWLGt6SxyN76h5Lf_id9tyVUzjR-qXNyJwXaGlZY,8129
|
|
97
100
|
funboost/core/lazy_impoter.py,sha256=5yToRBbTB338heR787ap5i-UAGN0FanUCkYfK9Nsgnk,4957
|
|
98
101
|
funboost/core/loggers.py,sha256=uy5mFLIUvKaVdJZLi6THyxqeuOmp9XEOKrH1Yci0zUM,2354
|
|
99
|
-
funboost/core/msg_result_getter.py,sha256=
|
|
102
|
+
funboost/core/msg_result_getter.py,sha256=wxJBTOsyPDptLbNYOIA7YwuDsDUKDpB5sFzj9_HPcPs,8106
|
|
100
103
|
funboost/core/muliti_process_enhance.py,sha256=tI3178inc5sqPh-jQc0XaTuUD1diIZyHuukBRk1Gp6Y,3595
|
|
104
|
+
funboost/core/serialization.py,sha256=Q6cAfbaqBCKw0AQwisbMNjOOD0csq0xdes5BHn1Nelo,412
|
|
101
105
|
funboost/core/task_id_logger.py,sha256=lR19HQcX6Pp8laURCD656xNpF_JP6nLB3zUKI69EWzE,864
|
|
102
106
|
funboost/core/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
103
107
|
funboost/core/cli/discovery_boosters.py,sha256=mbEyv0bUIGcmgkfXLI_Q1IK1QvVwKyro8XccuuMEA6o,3944
|
|
104
108
|
funboost/core/cli/funboost_cli_user_templ.py,sha256=XUpKLxRKtYfebPUM8wii64kB0HW8L7j9LnRpT0xCfQI,2243
|
|
105
109
|
funboost/core/cli/funboost_fire.py,sha256=OT0SNi9Zb0Tom2E0cWuArQs0obUowAA_rpCF7GdaKPs,5065
|
|
106
110
|
funboost/factories/__init__.py,sha256=s7kKKjR1HU5eMjPD6r5b-SXTVMo1zBp2JjOAtkyt5Yo,178
|
|
107
|
-
funboost/factories/broker_kind__publsiher_consumer_type_map.py,sha256
|
|
111
|
+
funboost/factories/broker_kind__publsiher_consumer_type_map.py,sha256=-kKhV65KnRf86b353PJuaEMXMolfV4B2CtTF1wD1kFQ,10189
|
|
108
112
|
funboost/factories/consumer_factory.py,sha256=EaAw3OZJkGepkQxKkDvMshHjIVOQva_N6nUEhLO4JwU,1500
|
|
109
113
|
funboost/factories/publisher_factotry.py,sha256=4651sxnbIAi6sFEUQdlUuv8UkbMQIE_Pbzm-1DimAs8,2535
|
|
110
114
|
funboost/function_result_web/app.py,sha256=WFAsAoPqCVeTxKS31UvkAhuRqUurg-j8D3c9RtHZEyY,5059
|
|
@@ -125,18 +129,19 @@ funboost/function_result_web/static/js/jquery-1.11.0.min.js,sha256=ryQZ3RXgnqkTz
|
|
|
125
129
|
funboost/function_result_web/templates/index.html,sha256=YM0582Q4t2da-xBf3Ga0McIfcsT9H98rjZck-irMkGo,20387
|
|
126
130
|
funboost/function_result_web/templates/login.html,sha256=q37dj7O0LeyiV38Zd5P1Qn_qmhjdFomuYTRY1Yk48Bo,2007
|
|
127
131
|
funboost/publishers/__init__.py,sha256=xqBHlvsJQVPfbdvP84G0LHmVB7-pFBS7vDnX1Uo9pVY,131
|
|
128
|
-
funboost/publishers/base_publisher.py,sha256=
|
|
132
|
+
funboost/publishers/base_publisher.py,sha256=K6ztxeCWCDakEFUXEtA-lmmcccY8fLEKFlOLIVzjz58,17718
|
|
129
133
|
funboost/publishers/celery_publisher.py,sha256=uc9N1uLW74skUCw8dsnvxORM2O3cy4SiI7tUZRmvkHA,2336
|
|
130
134
|
funboost/publishers/celery_publisher000.py,sha256=2XLOyU2__vlIUTi5L15uf0BJqAIjxbc3kCLIRDSOY9w,3966
|
|
131
135
|
funboost/publishers/confluent_kafka_publisher.py,sha256=B4rF6gljixOMyN6L2eL1gzqTv97uoy7TTzgKUhHljEQ,4749
|
|
132
136
|
funboost/publishers/dramatiq_publisher.py,sha256=IH9F-Ps1r94WDu2a7cZbJqWlBgblDbEcpjGj2rl-9WE,1413
|
|
133
137
|
funboost/publishers/empty_publisher.py,sha256=Com5m-mkjXpcWxKZZneymhLNaRJNaGAtvwjhwHmECgg,870
|
|
138
|
+
funboost/publishers/faststream_publisher.py,sha256=ndGDHz53s_u5NsSi2vK7_Zll2m3lfqzQ8iaNPGHo6oE,2223
|
|
134
139
|
funboost/publishers/http_publisher.py,sha256=pS3z_AVqH6h4PAgqB7usihvzLJP5ZzfPKQRMQfHrJHQ,753
|
|
135
140
|
funboost/publishers/httpsqs_publisher.py,sha256=PS6h8-mn3wYFfMOsPt4tal8p0yZgYgrYYO9ZnIl9CwU,2737
|
|
136
141
|
funboost/publishers/huey_publisher.py,sha256=9HBrsqTO61iPB1nI5fYOQNPuOaX4I4Wmb1BRNODAE_0,1118
|
|
137
142
|
funboost/publishers/kafka_publisher.py,sha256=5qOkNl1SFh4TQaVg0hJSF2ms7T76bkpF6ZtjjLaW8Vg,2060
|
|
138
143
|
funboost/publishers/kombu_publisher.py,sha256=Z0JKF_-xKJSTc21jqhIwphDUHUPO2X3wVojt-rHhDlM,5415
|
|
139
|
-
funboost/publishers/local_python_queue_publisher.py,sha256=
|
|
144
|
+
funboost/publishers/local_python_queue_publisher.py,sha256=292NKW7X4MCMMPvfMDb-6_BdA997lda7-lOlODIAaOY,3477
|
|
140
145
|
funboost/publishers/meomory_deque_publisher.py,sha256=0q6WKQ8ohnhlXDgXkxWGsImZCnwB12nFD6kUjldRQiw,1303
|
|
141
146
|
funboost/publishers/mongomq_publisher.py,sha256=xQr3KMQEKksX4OEvzPlCl8v1VeBHaoZtYw2QujOUyGo,1874
|
|
142
147
|
funboost/publishers/mqtt_publisher.py,sha256=nL-pweqL8lkoRUliNKQtdXgryG0wZO7iIvjFdr1it1s,3131
|
|
@@ -164,6 +169,7 @@ funboost/publishers/txt_file_publisher.py,sha256=dqrfBt1ejjwJbwFS3UqPo4VFDCa6NWb
|
|
|
164
169
|
funboost/publishers/udp_publisher.py,sha256=TOiKrhmCMjx4teqIgdUwRic0lxyK2cupinafsz--wzY,1194
|
|
165
170
|
funboost/publishers/zeromq_publisher.py,sha256=SHFzSLPLkoht9Ey-q894g59sCuu6IM603xDV0JD4CrY,1024
|
|
166
171
|
funboost/queues/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
172
|
+
funboost/queues/memory_queues_map.py,sha256=e1S_cnjnCVI4DBsA_iupF51S_eX4OvCtlefQCqS1TYA,424
|
|
167
173
|
funboost/queues/peewee_queue.py,sha256=FrwegrilkHZG6Y1cGdl5Bt_UtA25f7m5TJQJMZ9YnJI,5280
|
|
168
174
|
funboost/queues/sqla_queue.py,sha256=b-2QPvvuMxklm41ibZhGKehaAV9trXBQFCOHzgThx_s,11080
|
|
169
175
|
funboost/timing_job/__init__.py,sha256=uMKIiZOqr8aXGPxZhDcVVeeNTsDi-S7kOkLc1nHaLQw,9099
|
|
@@ -179,7 +185,7 @@ funboost/utils/custom_pysnooper.py,sha256=7yXLKEMY_JjPRRt0Y0N-wV2CFhILlYNh40Y6uR
|
|
|
179
185
|
funboost/utils/decorators.py,sha256=lyi9TCBg__7xkoV17AZhRItTn95vU2XMtOxfXJVV5B4,26601
|
|
180
186
|
funboost/utils/develop_log.py,sha256=Wsx0ongGjTit5xqgk1BztYlVEkC6d0-Y7GENXLedVqY,271
|
|
181
187
|
funboost/utils/expire_lock.py,sha256=AOkd1KlvZeIwQaz8ZoKxLpGxWgqQ4mfNHcFphh04o8Q,4732
|
|
182
|
-
funboost/utils/json_helper.py,sha256=
|
|
188
|
+
funboost/utils/json_helper.py,sha256=kwN5O-0Z3_9KS3JdBx-BltS9LI3Rfoq329vgkxMPVw4,2286
|
|
183
189
|
funboost/utils/mongo_util.py,sha256=g2AdsanKm2v9X-OaTCS6hx_0JvRw5WukXIttN3TD9sI,3069
|
|
184
190
|
funboost/utils/monkey_color_log.py,sha256=QChhQMTB6phZ2eBaPq-9tFZF1n7pWeJgmJPIB_ugkvs,7367
|
|
185
191
|
funboost/utils/monkey_patches.py,sha256=vGmtPuTwNLbS8T3gpufSC_cD8_Vnp85roZrCpJZUSE4,2890
|
|
@@ -271,9 +277,9 @@ funboost/utils/pysnooper_ydf/utils.py,sha256=evSmGi_Oul7vSP47AJ0DLjFwoCYCfunJZ1m
|
|
|
271
277
|
funboost/utils/pysnooper_ydf/variables.py,sha256=QejRDESBA06KG9OH4sBT4J1M55eaU29EIHg8K_igaXo,3693
|
|
272
278
|
funboost/utils/times/__init__.py,sha256=Y4bQD3SIA_E7W2YvHq2Qdi0dGM4H2DxyFNdDOuFOq1w,2417
|
|
273
279
|
funboost/utils/times/version.py,sha256=11XfnZVVzOgIhXXdeN_mYfdXThfrsbQHpA0wCjz-hpg,17
|
|
274
|
-
funboost-45.
|
|
275
|
-
funboost-45.
|
|
276
|
-
funboost-45.
|
|
277
|
-
funboost-45.
|
|
278
|
-
funboost-45.
|
|
279
|
-
funboost-45.
|
|
280
|
+
funboost-45.6.dist-info/LICENSE,sha256=9EPP2ktG_lAPB8PjmWV-c9BiaJHc_FP6pPLcUrUwx0E,11562
|
|
281
|
+
funboost-45.6.dist-info/METADATA,sha256=d2uFQ75R_EbBoYH8UHkCQaFNVKkAXqS8Brg9PvXRhMg,32533
|
|
282
|
+
funboost-45.6.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
|
283
|
+
funboost-45.6.dist-info/entry_points.txt,sha256=BQMqRALuw-QT9x2d7puWaUHriXfy3wIzvfzF61AnSSI,97
|
|
284
|
+
funboost-45.6.dist-info/top_level.txt,sha256=K8WuKnS6MRcEWxP1NvbmCeujJq6TEfbsB150YROlRw0,9
|
|
285
|
+
funboost-45.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|