funboost 50.3__py3-none-any.whl → 50.4__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/constant.py +4 -0
- funboost/consumers/base_consumer.py +93 -98
- funboost/consumers/celery_consumer.py +1 -1
- funboost/consumers/dramatiq_consumer.py +0 -5
- funboost/consumers/grpc_consumer.py +1 -1
- funboost/consumers/http_consumer.py +1 -1
- funboost/consumers/http_consumer_aiohttp_old.py +1 -1
- funboost/consumers/huey_consumer.py +2 -5
- funboost/consumers/kafka_consumer.py +0 -2
- funboost/consumers/kafka_consumer_manually_commit.py +0 -1
- funboost/consumers/kombu_consumer.py +0 -39
- funboost/consumers/mysql_cdc_consumer.py +1 -3
- funboost/consumers/pulsar_consumer.py +10 -5
- funboost/consumers/rabbitmq_amqpstorm_consumer.py +7 -8
- funboost/consumers/rabbitmq_complex_routing_consumer.py +54 -0
- funboost/consumers/redis_consumer.py +1 -1
- funboost/consumers/redis_consumer_ack_able.py +1 -1
- funboost/consumers/redis_consumer_ack_using_timeout.py +2 -6
- funboost/consumers/redis_consumer_priority.py +1 -1
- funboost/consumers/redis_stream_consumer.py +1 -3
- funboost/consumers/tcp_consumer.py +1 -1
- funboost/consumers/udp_consumer.py +1 -1
- funboost/consumers/zeromq_consumer.py +1 -1
- funboost/contrib/save_function_result_status/__init__.py +0 -0
- funboost/contrib/{save_result_status_to_sqldb.py → save_function_result_status/save_result_status_to_sqldb.py} +8 -41
- funboost/contrib/save_function_result_status/save_result_status_use_dataset.py +47 -0
- funboost/core/booster.py +7 -1
- funboost/core/broker_kind__exclusive_config_default_define.py +229 -0
- funboost/core/funboost_time.py +3 -82
- funboost/core/func_params_model.py +9 -3
- funboost/core/helper_funs.py +2 -2
- funboost/factories/broker_kind__publsiher_consumer_type_map.py +5 -0
- funboost/funboost_config_deafult.py +0 -3
- funboost/function_result_web/templates/fun_result_table.html +1 -1
- funboost/publishers/base_publisher.py +3 -2
- funboost/publishers/rabbitmq_amqpstorm_publisher.py +8 -7
- funboost/publishers/rabbitmq_complex_routing_publisher.py +84 -0
- funboost/utils/redis_manager.py +11 -5
- {funboost-50.3.dist-info → funboost-50.4.dist-info}/METADATA +156 -97
- {funboost-50.3.dist-info → funboost-50.4.dist-info}/RECORD +44 -40
- {funboost-50.3.dist-info → funboost-50.4.dist-info}/WHEEL +1 -1
- funboost-50.3.dist-info/LICENSE +0 -203
- {funboost-50.3.dist-info → funboost-50.4.dist-info}/entry_points.txt +0 -0
- {funboost-50.3.dist-info → funboost-50.4.dist-info}/top_level.txt +0 -0
funboost/core/funboost_time.py
CHANGED
|
@@ -5,7 +5,7 @@ import datetime
|
|
|
5
5
|
|
|
6
6
|
import typing
|
|
7
7
|
import threading
|
|
8
|
-
from nb_time import NbTime
|
|
8
|
+
from nb_time import NbTime,NowTimeStrCache
|
|
9
9
|
from funboost.funboost_config_deafult import FunboostCommonConfig
|
|
10
10
|
|
|
11
11
|
|
|
@@ -29,87 +29,8 @@ class FunboostTime(NbTime):
|
|
|
29
29
|
return t_str
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
_DIGIT_MAP = {i: f'{i:02d}' for i in range(100)}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def _gen_2_dig_number(n):
|
|
39
|
-
return _DIGIT_MAP[n]
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def get_now_time_str_by_tz(tz_name: str = None) -> str:
|
|
43
|
-
# 生成100万次当前时间字符串%Y-%m-%d %H:%M:%S仅需1.9秒.
|
|
44
|
-
"""
|
|
45
|
-
根据时区名(如 'Asia/Shanghai')返回当前时间字符串,格式:'%Y-%m-%d %H:%M:%S'
|
|
46
|
-
|
|
47
|
-
兼容 Python 3.6+,优先使用 zoneinfo(3.9+),否则尝试 pytz
|
|
48
|
-
|
|
49
|
-
:param tz_name: IANA 时区名称,如 'Asia/Shanghai', 'America/New_York'
|
|
50
|
-
:return: 格式化时间字符串
|
|
51
|
-
"""
|
|
52
|
-
# 检查缓存
|
|
53
|
-
tz_name = tz_name or FunboostCommonConfig.TIMEZONE
|
|
54
|
-
if tz_name not in _tz_cache:
|
|
55
|
-
if sys.version_info >= (3, 9):
|
|
56
|
-
from zoneinfo import ZoneInfo
|
|
57
|
-
_tz_cache[tz_name] = ZoneInfo(tz_name)
|
|
58
|
-
else:
|
|
59
|
-
# Python < 3.9,使用 pytz
|
|
60
|
-
_tz_cache[tz_name] = pytz.timezone(tz_name)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
tz = _tz_cache[tz_name]
|
|
64
|
-
|
|
65
|
-
# 获取当前时间并格式化(注意:datetime.now(tz) 是最高效的方式)
|
|
66
|
-
now = datetime.datetime.now(tz)
|
|
67
|
-
# return f'{now.year:04d}-{now.month:02d}-{now.day:02d} {now.hour:02d}:{now.minute:02d}:{now.second:02d}'
|
|
68
|
-
# return now.strftime("%Y-%m-%d %H:%M:%S")
|
|
69
|
-
return f'{now.year}-{_gen_2_dig_number(now.month)}-{_gen_2_dig_number(now.day)} {_gen_2_dig_number(now.hour)}:{_gen_2_dig_number(now.minute)}:{_gen_2_dig_number(now.second)}'
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
class NowTimeStrCache:
|
|
73
|
-
# 生成100万次当前时间字符串%Y-%m-%d %H:%M:%S仅需0.4秒.
|
|
74
|
-
# 全局变量,用于存储缓存的时间字符串和对应的整秒时间戳
|
|
75
|
-
_cached_time_str: typing.Optional[str] = None
|
|
76
|
-
_cached_time_second: int = 0
|
|
77
|
-
|
|
78
|
-
# 为了线程安全,使用锁。在极高并发下,锁的开销远小于每毫秒都进行时间格式化。
|
|
79
|
-
_time_cache_lock = threading.Lock()
|
|
80
|
-
|
|
81
|
-
@classmethod
|
|
82
|
-
def fast_get_now_time_str(cls,timezone_str:str=None) -> str:
|
|
83
|
-
"""
|
|
84
|
-
获取当前时间字符串,格式为 '%Y-%m-%d %H:%M:%S'。
|
|
85
|
-
通过缓存机制,同一秒内的多次调用直接返回缓存结果,极大提升性能。
|
|
86
|
-
适用于对时间精度要求不高(秒级即可)的高并发场景。
|
|
87
|
-
:return: 格式化后的时间字符串,例如 '2024-06-12 15:30:45'
|
|
88
|
-
"""
|
|
89
|
-
timezone_str = timezone_str or FunboostCommonConfig.TIMEZONE
|
|
90
|
-
|
|
91
|
-
# 获取当前的整秒时间戳(去掉小数部分)
|
|
92
|
-
current_second = int(time.time())
|
|
93
|
-
|
|
94
|
-
# 如果缓存的时间戳与当前秒数一致,直接返回缓存的字符串。
|
|
95
|
-
if current_second == cls._cached_time_second:
|
|
96
|
-
return cls._cached_time_str
|
|
97
|
-
|
|
98
|
-
# 如果不一致,说明进入新的一秒,需要重新计算并更新缓存。
|
|
99
|
-
# 使用锁确保在多线程环境下,只有一个线程会执行更新操作。
|
|
100
|
-
|
|
101
|
-
with cls._time_cache_lock:
|
|
102
|
-
# 双重检查锁定 (Double-Checked Locking),防止在等待锁的过程中,其他线程已经更新了缓存。
|
|
103
|
-
if current_second == cls._cached_time_second:
|
|
104
|
-
return cls._cached_time_str
|
|
105
|
-
|
|
106
|
-
# 重新计算时间字符串。这里直接使用 time.strftime,因为它在秒级更新的场景下性能足够。
|
|
107
|
-
# 我们不需要像 Funboost 那样为每一毫秒的调用都去做查表优化。
|
|
108
|
-
now = datetime.datetime.now(tz=pytz.timezone(timezone_str))
|
|
109
|
-
cls._cached_time_str = now.strftime('%Y-%m-%d %H:%M:%S', )
|
|
110
|
-
cls._cached_time_second = current_second
|
|
111
|
-
|
|
112
|
-
return cls._cached_time_str
|
|
32
|
+
def fast_get_now_time_str() -> str:
|
|
33
|
+
return NowTimeStrCache.fast_get_now_time_str(FunboostCommonConfig.TIMEZONE)
|
|
113
34
|
|
|
114
35
|
|
|
115
36
|
if __name__ == '__main__':
|
|
@@ -212,9 +212,15 @@ class BoosterParams(BaseJsonAbleModel):
|
|
|
212
212
|
consuming_function_raw: typing.Optional[typing.Callable] = None # 不需要传递,自动生成
|
|
213
213
|
consuming_function_name: str = '' # 不需要传递,自动生成
|
|
214
214
|
|
|
215
|
+
|
|
216
|
+
"""
|
|
217
|
+
# 加上一个不同种类中间件非通用的配置,不同中间件自身独有的配置,不是所有中间件都兼容的配置,因为框架支持30种消息队列,消息队列不仅仅是一般的先进先出queue这么简单的概念,
|
|
218
|
+
# 例如kafka支持消费者组,rabbitmq也支持各种独特概念例如各种ack机制 复杂路由机制,有的中间件原生能支持消息优先级有的中间件不支持,每一种消息队列都有独特的配置参数意义,可以通过这里传递。
|
|
219
|
+
# 每种中间件能传递的键值对可以看 funboost/core/broker_kind__exclusive_config_default.py 的 BROKER_EXCLUSIVE_CONFIG_DEFAULT 属性。
|
|
220
|
+
"""
|
|
221
|
+
broker_exclusive_config: dict = {}
|
|
222
|
+
|
|
215
223
|
|
|
216
|
-
broker_exclusive_config: dict = {} # 加上一个不同种类中间件非通用的配置,不同中间件自身独有的配置,不是所有中间件都兼容的配置,因为框架支持30种消息队列,消息队列不仅仅是一般的先进先出queue这么简单的概念,
|
|
217
|
-
# 例如kafka支持消费者组,rabbitmq也支持各种独特概念例如各种ack机制 复杂路由机制,有的中间件原生能支持消息优先级有的中间件不支持,每一种消息队列都有独特的配置参数意义,可以通过这里传递。每种中间件能传递的键值对可以看consumer类的 BROKER_EXCLUSIVE_CONFIG_DEFAULT
|
|
218
224
|
|
|
219
225
|
should_check_publish_func_params: bool = True # 消息发布时候是否校验消息发布内容,比如有的人发布消息,函数只接受a,b两个入参,他去传2个入参,或者传参不存在的参数名字; 如果消费函数加了装饰器 ,你非要写*args,**kwargs,那就需要关掉发布消息时候的函数入参检查
|
|
220
226
|
publish_msg_log_use_full_msg: bool = False # 发布到消息队列的消息内容的日志,是否显示消息的完整体,还是只显示函数入参。
|
|
@@ -241,7 +247,7 @@ class BoosterParams(BaseJsonAbleModel):
|
|
|
241
247
|
|
|
242
248
|
使用场景见文档 4b.6 章节.
|
|
243
249
|
"""
|
|
244
|
-
user_options: dict = {} #
|
|
250
|
+
user_options: dict = {} # 用户自定义的配置,高级用户或者奇葩需求可以用得到,用户可以自由发挥,存放任何设置,例如配合 consumer_override_cls中读取 或 register_custom_broker 使用
|
|
245
251
|
|
|
246
252
|
|
|
247
253
|
auto_generate_info: dict = {} # 自动生成的信息,不需要用户主动传参.
|
funboost/core/helper_funs.py
CHANGED
|
@@ -3,7 +3,7 @@ import pytz
|
|
|
3
3
|
import time
|
|
4
4
|
import uuid
|
|
5
5
|
import datetime
|
|
6
|
-
from funboost.core.funboost_time import FunboostTime,
|
|
6
|
+
from funboost.core.funboost_time import FunboostTime, fast_get_now_time_str
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def get_publish_time(paramsx: dict):
|
|
@@ -62,7 +62,7 @@ class MsgGenerater:
|
|
|
62
62
|
def generate_publish_time_format() -> str:
|
|
63
63
|
# return FunboostTime().get_str() # 性能不好
|
|
64
64
|
# return get_now_time_str_by_tz() # 2秒100万次
|
|
65
|
-
return
|
|
65
|
+
return fast_get_now_time_str() # 0.4秒100万次
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
@classmethod
|
|
@@ -115,6 +115,11 @@ def regist_to_funboost(broker_kind: str):
|
|
|
115
115
|
from funboost.consumers.rabbitmq_amqpstorm_consumer import RabbitmqConsumerAmqpStorm
|
|
116
116
|
register_custom_broker(BrokerEnum.RABBITMQ_AMQPSTORM, RabbitmqPublisherUsingAmqpStorm, RabbitmqConsumerAmqpStorm)
|
|
117
117
|
|
|
118
|
+
if broker_kind == BrokerEnum.RABBITMQ_COMPLEX_ROUTING:
|
|
119
|
+
from funboost.publishers.rabbitmq_complex_routing_publisher import RabbitmqComplexRoutingPublisher
|
|
120
|
+
from funboost.consumers.rabbitmq_complex_routing_consumer import RabbitmqComplexRoutingConsumer
|
|
121
|
+
register_custom_broker(BrokerEnum.RABBITMQ_COMPLEX_ROUTING, RabbitmqComplexRoutingPublisher, RabbitmqComplexRoutingConsumer)
|
|
122
|
+
|
|
118
123
|
if broker_kind == BrokerEnum.RABBITMQ_RABBITPY:
|
|
119
124
|
from funboost.publishers.rabbitmq_rabbitpy_publisher import RabbitmqPublisherUsingRabbitpy
|
|
120
125
|
from funboost.consumers.rabbitmq_rabbitpy_consumer import RabbitmqConsumerRabbitpy
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import logging
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
import pytz
|
|
5
|
-
from funboost.constant import BrokerEnum, ConcurrentModeEnum
|
|
6
|
-
from funboost.core.func_params_model import FunctionResultStatusPersistanceConfig
|
|
7
4
|
from funboost.utils.simple_data_class import DataClassBase
|
|
8
5
|
from nb_log import nb_log_config_default
|
|
9
6
|
|
|
@@ -325,7 +325,7 @@
|
|
|
325
325
|
var time_start_obj = new Date(item.time_start * 1000);
|
|
326
326
|
var time_start_str = dateToString(time_start_obj);
|
|
327
327
|
|
|
328
|
-
tr = tr.format(displayLevel, item.host_process + ' - ' + item.script_name, item.function, item.params_str, item.result, item.
|
|
328
|
+
tr = tr.format(displayLevel, item.host_process + ' - ' + item.script_name, item.function, item.params_str, item.result, item.publish_time_format,
|
|
329
329
|
time_start_str, item.time_cost, item.run_times, run_status_text, successText, item.exception, item.total_thread);
|
|
330
330
|
html += tr;
|
|
331
331
|
}
|
|
@@ -10,7 +10,6 @@ import atexit
|
|
|
10
10
|
import json
|
|
11
11
|
import logging
|
|
12
12
|
import multiprocessing
|
|
13
|
-
from re import S
|
|
14
13
|
import sys
|
|
15
14
|
import threading
|
|
16
15
|
import time
|
|
@@ -20,6 +19,7 @@ from threading import Lock
|
|
|
20
19
|
|
|
21
20
|
import nb_log
|
|
22
21
|
from funboost.constant import ConstStrForClassMethod, FunctionKind
|
|
22
|
+
from funboost.core.broker_kind__exclusive_config_default_define import generate_broker_exclusive_config
|
|
23
23
|
from funboost.core.func_params_model import PublisherParams, PriorityConsumingControlConfig
|
|
24
24
|
from funboost.core.function_result_status_saver import FunctionResultStatus
|
|
25
25
|
from funboost.core.helper_funs import MsgGenerater
|
|
@@ -140,11 +140,12 @@ class PublishParamsChecker(FunboostFileLoggerMixin):
|
|
|
140
140
|
class AbstractPublisher(LoggerLevelSetterMixin, metaclass=abc.ABCMeta, ):
|
|
141
141
|
def __init__(self, publisher_params: PublisherParams, ):
|
|
142
142
|
self.publisher_params = publisher_params
|
|
143
|
+
|
|
143
144
|
self.queue_name = self._queue_name = publisher_params.queue_name
|
|
144
145
|
self.logger: logging.Logger
|
|
145
146
|
self._build_logger()
|
|
146
147
|
self.publish_params_checker = PublishParamsChecker(publisher_params.consuming_function) if publisher_params.consuming_function else None
|
|
147
|
-
|
|
148
|
+
self.publisher_params.broker_exclusive_config = generate_broker_exclusive_config(self.publisher_params.broker_kind,self.publisher_params.broker_exclusive_config,self.logger)
|
|
148
149
|
self.has_init_broker = 0
|
|
149
150
|
self._lock_for_count = Lock()
|
|
150
151
|
self._current_time = None
|
|
@@ -12,19 +12,20 @@ from funboost.utils import decorators
|
|
|
12
12
|
class RabbitmqPublisherUsingAmqpStorm(AbstractPublisher):
|
|
13
13
|
# 使用amqpstorm包实现的mq操作。
|
|
14
14
|
# 实例属性没在__init__里面写,造成代码补全很麻烦,写在这里做类属性,方便pycharm补全
|
|
15
|
-
connection
|
|
16
|
-
channel
|
|
17
|
-
channel_wrapper_by_ampqstormbaic
|
|
18
|
-
queue
|
|
19
|
-
|
|
15
|
+
connection : amqpstorm.UriConnection
|
|
16
|
+
channel : amqpstorm.Channel
|
|
17
|
+
channel_wrapper_by_ampqstormbaic : AmqpStormBasic
|
|
18
|
+
queue : AmqpStormQueue
|
|
19
|
+
|
|
20
20
|
|
|
21
21
|
def custom_init(self):
|
|
22
22
|
arguments = {} # {'x-queue-type':'classic'} classic stream lazy quorum
|
|
23
23
|
if self.publisher_params.broker_exclusive_config.get('x-max-priority'):
|
|
24
24
|
arguments['x-max-priority'] = self.publisher_params.broker_exclusive_config['x-max-priority']
|
|
25
|
-
self.
|
|
25
|
+
self._queue_durable = self.publisher_params.broker_exclusive_config['queue_durable']
|
|
26
|
+
self.queue_declare_params = dict(queue=self._queue_name, durable=self._queue_durable, arguments=arguments,auto_delete=False)
|
|
26
27
|
|
|
27
|
-
# noinspection
|
|
28
|
+
# noinspection PyAttrib_durableuteOutsideInit
|
|
28
29
|
# @decorators.synchronized
|
|
29
30
|
def init_broker(self):
|
|
30
31
|
# username=app_config.RABBITMQ_USER, password=app_config.RABBITMQ_PASS, host=app_config.RABBITMQ_HOST, port=app_config.RABBITMQ_PORT, virtual_host=app_config.RABBITMQ_VIRTUAL_HOST, heartbeat=60 * 10
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# @Author : ydf
|
|
3
|
+
# @Time : 2022/8/8 0008 12:06
|
|
4
|
+
import amqpstorm
|
|
5
|
+
from amqpstorm.basic import Basic as AmqpStormBasic
|
|
6
|
+
from amqpstorm.queue import Queue as AmqpStormQueue
|
|
7
|
+
from funboost.funboost_config_deafult import BrokerConnConfig
|
|
8
|
+
from funboost.publishers.base_publisher import AbstractPublisher, deco_mq_conn_error
|
|
9
|
+
from funboost.utils import decorators
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class RabbitmqComplexRoutingPublisher(AbstractPublisher):
|
|
13
|
+
# 使用amqpstorm包实现的mq操作。
|
|
14
|
+
# 实例属性没在__init__里面写,造成代码补全很麻烦,写在这里做类属性,方便pycharm补全
|
|
15
|
+
connection : amqpstorm.UriConnection
|
|
16
|
+
channel : amqpstorm.Channel
|
|
17
|
+
channel_wrapper_by_ampqstormbaic : AmqpStormBasic
|
|
18
|
+
queue : AmqpStormQueue
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def custom_init(self):
|
|
22
|
+
arguments = {} # {'x-queue-type':'classic'} classic stream lazy quorum
|
|
23
|
+
if self.publisher_params.broker_exclusive_config.get('x-max-priority'):
|
|
24
|
+
arguments['x-max-priority'] = self.publisher_params.broker_exclusive_config['x-max-priority']
|
|
25
|
+
self._queue_durable = self.publisher_params.broker_exclusive_config['queue_durable']
|
|
26
|
+
self.queue_declare_params = dict(queue=self._queue_name, durable=self._queue_durable,
|
|
27
|
+
arguments=arguments,auto_delete=False)
|
|
28
|
+
|
|
29
|
+
self._exchange_name = self.publisher_params.broker_exclusive_config['exchange_name']
|
|
30
|
+
self._exchange_type = self.publisher_params.broker_exclusive_config['exchange_type']
|
|
31
|
+
# 如果用户没有在 broker_exclusive_config 中指定 routing_key_for_publish,则默认使用队列名作为 routing_key
|
|
32
|
+
self._routing_key_for_publish = self.publisher_params.broker_exclusive_config.get('routing_key_for_publish') or self._queue_name # 这里你已经用了很好的实践
|
|
33
|
+
|
|
34
|
+
self._exchange_declare_durable = self.publisher_params.broker_exclusive_config['exchange_declare_durable']
|
|
35
|
+
|
|
36
|
+
self.init_broker()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# noinspection PyAttributeOutsideInit
|
|
40
|
+
# @decorators.synchronized
|
|
41
|
+
def init_broker(self):
|
|
42
|
+
# username=app_config.RABBITMQ_USER, password=app_config.RABBITMQ_PASS, host=app_config.RABBITMQ_HOST, port=app_config.RABBITMQ_PORT, virtual_host=app_config.RABBITMQ_VIRTUAL_HOST, heartbeat=60 * 10
|
|
43
|
+
self.logger.warning(f'使用AmqpStorm包 链接mq')
|
|
44
|
+
self.connection = amqpstorm.UriConnection(
|
|
45
|
+
f'amqp://{BrokerConnConfig.RABBITMQ_USER}:{BrokerConnConfig.RABBITMQ_PASS}@{BrokerConnConfig.RABBITMQ_HOST}:{BrokerConnConfig.RABBITMQ_PORT}/{BrokerConnConfig.RABBITMQ_VIRTUAL_HOST}?heartbeat={60 * 10}&timeout=20000'
|
|
46
|
+
)
|
|
47
|
+
self.channel = self.connection.channel() # type:amqpstorm.Channel
|
|
48
|
+
self.channel_wrapper_by_ampqstormbaic = AmqpStormBasic(self.channel)
|
|
49
|
+
# 发布者不声明队列,队列的声明和绑定完全由消费者负责。
|
|
50
|
+
if self._exchange_name:
|
|
51
|
+
self.channel.exchange.declare(exchange=self._exchange_name, exchange_type=self._exchange_type,
|
|
52
|
+
durable=self._exchange_declare_durable)
|
|
53
|
+
|
|
54
|
+
# @decorators.tomorrow_threads(10)
|
|
55
|
+
@deco_mq_conn_error
|
|
56
|
+
def concrete_realization_of_publish(self, msg: str):
|
|
57
|
+
routing_key_publish_dynamic = self._get_from_other_extra_params('routing_key_for_publish', msg)
|
|
58
|
+
routing_key_publish = routing_key_publish_dynamic if routing_key_publish_dynamic is not None else self._routing_key_for_publish
|
|
59
|
+
# 核心修正2:为 headers 交换机添加 headers 支持
|
|
60
|
+
headers = self._get_from_other_extra_params('headers_for_publish', msg)
|
|
61
|
+
|
|
62
|
+
self.channel_wrapper_by_ampqstormbaic.publish(exchange=self._exchange_name,
|
|
63
|
+
routing_key=routing_key_publish,
|
|
64
|
+
body=msg,
|
|
65
|
+
properties={'delivery_mode': 2,
|
|
66
|
+
'priority': self._get_from_other_extra_params('priority', msg),
|
|
67
|
+
'headers': headers}, )
|
|
68
|
+
# nb_print(msg)
|
|
69
|
+
|
|
70
|
+
@deco_mq_conn_error
|
|
71
|
+
def clear(self):
|
|
72
|
+
AmqpStormQueue(self.channel).purge(self._queue_name)
|
|
73
|
+
self.logger.warning(f'清除 {self._queue_name} 队列中的消息成功')
|
|
74
|
+
|
|
75
|
+
@deco_mq_conn_error
|
|
76
|
+
def get_message_count(self):
|
|
77
|
+
# noinspection PyUnresolvedReferences
|
|
78
|
+
return AmqpStormQueue(self.channel).declare(**self.queue_declare_params)['message_count']
|
|
79
|
+
|
|
80
|
+
# @deco_mq_conn_error
|
|
81
|
+
def close(self):
|
|
82
|
+
self.channel.close()
|
|
83
|
+
self.connection.close()
|
|
84
|
+
self.logger.warning('关闭amqpstorm包 链接mq')
|
funboost/utils/redis_manager.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# coding=utf8
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
|
+
import os
|
|
5
|
+
import threading
|
|
4
6
|
# import redis2 as redis
|
|
5
7
|
# import redis3
|
|
6
8
|
import redis5
|
|
@@ -25,14 +27,18 @@ def _get_redis_conn_kwargs_by_db(db):
|
|
|
25
27
|
|
|
26
28
|
class RedisManager(object):
|
|
27
29
|
_redis_db__conn_map = {}
|
|
30
|
+
_lock = threading.Lock()
|
|
28
31
|
|
|
29
32
|
def __init__(self, host='127.0.0.1', port=6379, db=0, username='', password='',ssl=False):
|
|
30
|
-
|
|
33
|
+
pid = os.getpid()
|
|
34
|
+
self._key = (host, port, db, username, password,ssl,pid)
|
|
31
35
|
if self._key not in self.__class__._redis_db__conn_map:
|
|
32
|
-
self.__class__.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
with self.__class__._lock:
|
|
37
|
+
if self._key not in self.__class__._redis_db__conn_map:
|
|
38
|
+
self.__class__._redis_db__conn_map[self._key] = redis5.Redis(host=host, port=port, db=db, username=username,
|
|
39
|
+
password=password, max_connections=100,
|
|
40
|
+
ssl=ssl,
|
|
41
|
+
decode_responses=True)
|
|
36
42
|
self.redis = self.__class__._redis_db__conn_map[self._key]
|
|
37
43
|
|
|
38
44
|
def get_redis(self) -> redis5.Redis:
|