funboost 48.7__py3-none-any.whl → 48.9__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/__main__.py +2 -0
- funboost/concurrent_pool/custom_threadpool_executor.py +1 -1
- funboost/constant.py +17 -2
- funboost/consumers/base_consumer.py +42 -28
- funboost/consumers/rabbitmq_amqpstorm_consumer.py +6 -1
- funboost/core/active_cousumer_info_getter.py +50 -10
- funboost/core/booster.py +2 -1
- funboost/core/cli/funboost_fire.py +10 -0
- funboost/core/current_task.py +17 -0
- funboost/core/func_params_model.py +21 -17
- funboost/core/loggers.py +1 -0
- funboost/core/msg_result_getter.py +1 -0
- funboost/funboost_config_deafult.py +1 -1
- funboost/function_result_web/__pycache__/app.cpython-37.pyc +0 -0
- funboost/function_result_web/__pycache__/app.cpython-39.pyc +0 -0
- funboost/function_result_web/__pycache__/functions.cpython-37.pyc +0 -0
- funboost/function_result_web/__pycache__/functions.cpython-39.pyc +0 -0
- funboost/function_result_web/app.py +42 -2
- funboost/function_result_web/app_debug_start.py +6 -0
- funboost/function_result_web/functions.py +66 -3
- funboost/function_result_web/static/js/form-memory.js +92 -0
- funboost/function_result_web/static/js_cdn/chart.js +20 -0
- funboost/function_result_web/static/js_cdn/tabulator-tables@5.5.0/dist/js/tabulator.min.js +1 -1
- funboost/function_result_web/templates/about.html +0 -9
- funboost/function_result_web/templates/conusme_speed.html +2 -2
- funboost/function_result_web/templates/fun_result_table.html +1 -1
- funboost/function_result_web/templates/index.html +64 -9
- funboost/function_result_web/templates/queue_op.html +419 -28
- funboost/function_result_web/templates/rpc_call.html +312 -0
- funboost/function_result_web/templates/running_consumer_by_ip.html +2 -2
- funboost/function_result_web/templates/running_consumer_by_queue_name.html +2 -2
- funboost/publishers/rabbitmq_amqpstorm_publisher.py +1 -1
- funboost/utils/ctrl_c_end.py +19 -1
- funboost/utils/dependency_packages_in_pythonpath/aioredis/readme.md +6 -0
- funboost/utils/dependency_packages_in_pythonpath/readme.md +6 -0
- {funboost-48.7.dist-info → funboost-48.9.dist-info}/METADATA +173 -81
- {funboost-48.7.dist-info → funboost-48.9.dist-info}/RECORD +42 -39
- {funboost-48.7.dist-info → funboost-48.9.dist-info}/WHEEL +1 -1
- funboost/function_result_web/templates/index_/321/204/342/225/225/320/235/321/205/320/237/320/277/321/206/320/232/320/250/321/205/320/237/320/260.html +0 -153
- {funboost-48.7.dist-info → funboost-48.9.dist-info}/LICENSE +0 -0
- {funboost-48.7.dist-info → funboost-48.9.dist-info}/entry_points.txt +0 -0
- {funboost-48.7.dist-info → funboost-48.9.dist-info}/top_level.txt +0 -0
|
@@ -12,6 +12,9 @@ import os
|
|
|
12
12
|
|
|
13
13
|
import datetime
|
|
14
14
|
import json
|
|
15
|
+
import traceback
|
|
16
|
+
|
|
17
|
+
from funboost.core.func_params_model import PriorityConsumingControlConfig
|
|
15
18
|
|
|
16
19
|
"""
|
|
17
20
|
pip install Flask flask_bootstrap flask_wtf wtforms flask_login
|
|
@@ -26,6 +29,7 @@ from flask_login import login_user, logout_user, login_required, LoginManager, U
|
|
|
26
29
|
import nb_log
|
|
27
30
|
from funboost import nb_print,ActiveCousumerProcessInfoGetter,BoostersManager,PublisherParams,RedisMixin
|
|
28
31
|
from funboost.function_result_web.functions import get_cols, query_result, get_speed, Statistic
|
|
32
|
+
from funboost.function_result_web import functions as app_functions
|
|
29
33
|
from funboost.core.active_cousumer_info_getter import QueueConusmerParamsGetter
|
|
30
34
|
from funboost.constant import RedisKeys
|
|
31
35
|
|
|
@@ -119,7 +123,8 @@ def logout():
|
|
|
119
123
|
@app.route('/')
|
|
120
124
|
@login_required
|
|
121
125
|
def index():
|
|
122
|
-
|
|
126
|
+
page = request.args.get('page')
|
|
127
|
+
return render_template('index.html', page=page)
|
|
123
128
|
|
|
124
129
|
|
|
125
130
|
@app.route('/query_cols')
|
|
@@ -238,6 +243,39 @@ def resume_consume(queue_name):
|
|
|
238
243
|
RedisMixin().redis_db_frame.hset(RedisKeys.REDIS_KEY_PAUSE_FLAG, queue_name,'0')
|
|
239
244
|
return jsonify({'success':True})
|
|
240
245
|
|
|
246
|
+
@app.route('/queue/get_msg_num',methods=['GET'])
|
|
247
|
+
def get_msg_num():
|
|
248
|
+
return jsonify(QueueConusmerParamsGetter().get_msg_num(ignore_report_ts=True))
|
|
249
|
+
|
|
250
|
+
@app.route('/rpc/rpc_call',methods=['POST'])
|
|
251
|
+
def rpc_call():
|
|
252
|
+
"""
|
|
253
|
+
class MsgItem(BaseModel):
|
|
254
|
+
queue_name: str # 队列名
|
|
255
|
+
msg_body: dict # 消息体,就是boost函数的入参字典,例如 {"x":1,"y":2}
|
|
256
|
+
need_result: bool = False # 发布消息后,是否需要返回结果
|
|
257
|
+
timeout: int = 60 # 等待结果返回的最大等待时间.
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
class PublishResponse(BaseModel):
|
|
261
|
+
succ: bool
|
|
262
|
+
msg: str
|
|
263
|
+
status_and_result: typing.Optional[dict] = None # 消费函数的消费状态和结果.
|
|
264
|
+
task_id:str
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
msg_item = request.get_json()
|
|
268
|
+
return jsonify(app_functions.rpc_call(**msg_item))
|
|
269
|
+
|
|
270
|
+
@app.route('/rpc/get_result_by_task_id',methods=['GET'])
|
|
271
|
+
def get_result_by_task_id():
|
|
272
|
+
res = app_functions.get_result_by_task_id(task_id=request.args.get('task_id'),
|
|
273
|
+
timeout=request.args.get('timeout') or 60)
|
|
274
|
+
if res['status_and_result'] is None:
|
|
275
|
+
return jsonify({'succ':False,'msg':'task_id不存在或者超时或者结果已经过期'})
|
|
276
|
+
return jsonify(res)
|
|
277
|
+
|
|
278
|
+
|
|
241
279
|
def start_funboost_web_manager(host='0.0.0.0', port=27018,block=False):
|
|
242
280
|
print('start_funboost_web_manager , sys.path :', sys.path)
|
|
243
281
|
def _start_funboost_web_manager():
|
|
@@ -246,7 +284,9 @@ def start_funboost_web_manager(host='0.0.0.0', port=27018,block=False):
|
|
|
246
284
|
_start_funboost_web_manager()
|
|
247
285
|
else:
|
|
248
286
|
threading.Thread(target=_start_funboost_web_manager).start()
|
|
249
|
-
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
250
290
|
if __name__ == '__main__':
|
|
251
291
|
# app.jinja_env.auto_reload = True
|
|
252
292
|
# with app.test_request_context():
|
|
@@ -6,9 +6,16 @@ import json
|
|
|
6
6
|
from pprint import pprint
|
|
7
7
|
import time
|
|
8
8
|
import copy
|
|
9
|
+
import traceback
|
|
9
10
|
from funboost import nb_print
|
|
11
|
+
from funboost.constant import RedisKeys
|
|
12
|
+
from funboost.core.booster import BoostersManager
|
|
13
|
+
from funboost.core.func_params_model import PriorityConsumingControlConfig, PublisherParams
|
|
14
|
+
from funboost.core.msg_result_getter import AsyncResult
|
|
15
|
+
from funboost.core.serialization import Serialization
|
|
10
16
|
from funboost.utils import time_util, decorators, LoggerMixin
|
|
11
17
|
from funboost.utils.mongo_util import MongoMixin
|
|
18
|
+
from funboost.utils.redis_manager import RedisMixin
|
|
12
19
|
|
|
13
20
|
# from test_frame.my_patch_frame_config import do_patch_frame_config
|
|
14
21
|
#
|
|
@@ -144,6 +151,55 @@ class Statistic(LoggerMixin):
|
|
|
144
151
|
t2.strftime('%Y-%m-%d %H:%M:%S'))
|
|
145
152
|
self.result['recent_60_seconds']['count_arr'].append(count)
|
|
146
153
|
|
|
154
|
+
def rpc_call(queue_name, msg_body, need_result, timeout):
|
|
155
|
+
|
|
156
|
+
status_and_result = None
|
|
157
|
+
task_id = None
|
|
158
|
+
try:
|
|
159
|
+
boost_params_json = RedisMixin().redis_db_frame.hget(RedisKeys.FUNBOOST_QUEUE__CONSUMER_PARAMS,queue_name)
|
|
160
|
+
boost_params_dict = Serialization.to_dict(boost_params_json)
|
|
161
|
+
broker_kind = boost_params_dict['broker_kind']
|
|
162
|
+
publisher = BoostersManager.get_cross_project_publisher(PublisherParams(queue_name=queue_name,
|
|
163
|
+
broker_kind=broker_kind,
|
|
164
|
+
publish_msg_log_use_full_msg=True))
|
|
165
|
+
|
|
166
|
+
if need_result:
|
|
167
|
+
# if booster.boost_params.is_using_rpc_mode is False:
|
|
168
|
+
# raise ValueError(f' need_result 为true,{booster.queue_name} 队列消费者 需要@boost设置支持rpc模式')
|
|
169
|
+
|
|
170
|
+
async_result: AsyncResult = publisher.publish(msg_body,priority_control_config=PriorityConsumingControlConfig(is_using_rpc_mode=True))
|
|
171
|
+
async_result.set_timeout(timeout)
|
|
172
|
+
status_and_result = async_result.status_and_result
|
|
173
|
+
# print(status_and_result)
|
|
174
|
+
task_id = async_result.task_id
|
|
175
|
+
else:
|
|
176
|
+
async_result =publisher.publish(msg_body)
|
|
177
|
+
task_id = async_result.task_id
|
|
178
|
+
if status_and_result['success'] is False:
|
|
179
|
+
return dict(succ=False, msg=f'{queue_name} 队列,消息发布成功,但是函数执行失败',
|
|
180
|
+
status_and_result=status_and_result,task_id=task_id)
|
|
181
|
+
return dict(succ=True, msg=f'{queue_name} 队列,消息发布成功',
|
|
182
|
+
status_and_result=status_and_result,task_id=task_id)
|
|
183
|
+
except Exception as e:
|
|
184
|
+
return dict(succ=False, msg=f'{queue_name} 队列,消息发布失败 {type(e)} {e} {traceback.format_exc()}',
|
|
185
|
+
status_and_result=status_and_result,task_id=task_id)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def get_result_by_task_id(task_id,timeout):
|
|
189
|
+
async_result = AsyncResult(task_id)
|
|
190
|
+
async_result.set_timeout(timeout)
|
|
191
|
+
status_and_result = async_result.status_and_result
|
|
192
|
+
if status_and_result is None:
|
|
193
|
+
return dict(succ=False, msg=f'{task_id} 不存在 或 超时 或 结果已过期',
|
|
194
|
+
status_and_result=status_and_result,task_id=task_id)
|
|
195
|
+
if status_and_result['success'] is False:
|
|
196
|
+
return dict(succ=False, msg=f'{task_id} 执行失败',
|
|
197
|
+
status_and_result=status_and_result,task_id=task_id)
|
|
198
|
+
return dict(succ=True, msg=f'task_id:{task_id} 获取结果成功',
|
|
199
|
+
status_and_result=status_and_result,task_id=task_id)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
147
203
|
|
|
148
204
|
if __name__ == '__main__':
|
|
149
205
|
# print(get_cols('4'))
|
|
@@ -152,6 +208,13 @@ if __name__ == '__main__':
|
|
|
152
208
|
# nb_print(get_speed_last_minute('queue_test54'))
|
|
153
209
|
|
|
154
210
|
# nb_print(get_speed('queue_test56', '2019-09-18 16:03:29', '2019-09-23 16:03:29'))
|
|
155
|
-
stat = Statistic('queue_test_f01t')
|
|
156
|
-
stat.build_result()
|
|
157
|
-
nb_print(stat.result)
|
|
211
|
+
# stat = Statistic('queue_test_f01t')
|
|
212
|
+
# stat.build_result()
|
|
213
|
+
# nb_print(stat.result)
|
|
214
|
+
|
|
215
|
+
# res = rpc_call('queue_test_g02t',{'x':1,'y':2},True,60)
|
|
216
|
+
|
|
217
|
+
res = get_result_by_task_id('3232',60)
|
|
218
|
+
print(res)
|
|
219
|
+
|
|
220
|
+
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// 表单记忆功能 - 保存和恢复iframe内的表单值
|
|
2
|
+
(function() {
|
|
3
|
+
// 简化版 - 只保存基本输入值
|
|
4
|
+
function saveFormInputs() {
|
|
5
|
+
const iframe = document.getElementById('content');
|
|
6
|
+
if (!iframe || !iframe.contentWindow) return;
|
|
7
|
+
|
|
8
|
+
const pageId = iframe.src.split('/').pop().replace('.html', '');
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
|
|
12
|
+
const formData = {};
|
|
13
|
+
|
|
14
|
+
// 保存所有输入元素值
|
|
15
|
+
const inputs = iframeDoc.querySelectorAll('input, textarea, select');
|
|
16
|
+
inputs.forEach(input => {
|
|
17
|
+
const inputId = input.id || input.name || input.getAttribute('placeholder');
|
|
18
|
+
if (inputId) {
|
|
19
|
+
formData[inputId] = input.value;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// 特殊处理下拉框的选中文本
|
|
24
|
+
const selects = iframeDoc.querySelectorAll('select');
|
|
25
|
+
selects.forEach(select => {
|
|
26
|
+
const inputId = select.id || select.name;
|
|
27
|
+
if (inputId && select.selectedIndex >= 0 && select.options[select.selectedIndex]) {
|
|
28
|
+
formData[`${inputId}_text`] = select.options[select.selectedIndex].text;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
localStorage.setItem(`funboost_form_${pageId}`, JSON.stringify(formData));
|
|
33
|
+
} catch (e) {
|
|
34
|
+
console.error("保存表单数据失败:", e);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 简化版 - 只恢复基本输入值
|
|
39
|
+
function restoreFormInputs() {
|
|
40
|
+
setTimeout(() => {
|
|
41
|
+
const iframe = document.getElementById('content');
|
|
42
|
+
if (!iframe || !iframe.contentWindow) return;
|
|
43
|
+
|
|
44
|
+
const pageId = iframe.src.split('/').pop().replace('.html', '');
|
|
45
|
+
const savedData = localStorage.getItem(`funboost_form_${pageId}`);
|
|
46
|
+
|
|
47
|
+
if (savedData) {
|
|
48
|
+
try {
|
|
49
|
+
const formData = JSON.parse(savedData);
|
|
50
|
+
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
|
|
51
|
+
|
|
52
|
+
// 恢复所有基本输入元素的值
|
|
53
|
+
Object.keys(formData).forEach(inputId => {
|
|
54
|
+
if (inputId.endsWith('_text')) return;
|
|
55
|
+
|
|
56
|
+
const input = iframeDoc.getElementById(inputId) ||
|
|
57
|
+
iframeDoc.querySelector(`[name="${inputId}"]`) ||
|
|
58
|
+
iframeDoc.querySelector(`[placeholder="${inputId}"]`);
|
|
59
|
+
|
|
60
|
+
if (input) {
|
|
61
|
+
input.value = formData[inputId];
|
|
62
|
+
|
|
63
|
+
// 触发change事件
|
|
64
|
+
const event = new Event('change', { bubbles: true });
|
|
65
|
+
input.dispatchEvent(event);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
} catch (e) {
|
|
69
|
+
console.error("恢复表单数据失败:", e);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}, 500);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 当DOM加载完成时初始化事件监听
|
|
76
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
77
|
+
// 监听iframe加载完成事件
|
|
78
|
+
const contentFrame = document.getElementById('content');
|
|
79
|
+
if (contentFrame) {
|
|
80
|
+
contentFrame.addEventListener('load', restoreFormInputs);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 在页面切换前保存
|
|
84
|
+
const navLinks = document.querySelectorAll('.sidebar .nav-link');
|
|
85
|
+
navLinks.forEach(link => {
|
|
86
|
+
link.addEventListener('click', saveFormInputs);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// 页面离开前保存
|
|
90
|
+
window.addEventListener('beforeunload', saveFormInputs);
|
|
91
|
+
});
|
|
92
|
+
})();
|