update watchlist
This commit is contained in:
36
app.py
36
app.py
@@ -11682,7 +11682,39 @@ def initialize_event_polling():
|
|||||||
print(f'[轮询] 只会推送 ID > {max(current_redis_max, db_max_id)} 的新事件')
|
print(f'[轮询] 只会推送 ID > {max(current_redis_max, db_max_id)} 的新事件')
|
||||||
print(f'[轮询] ========== 初始化完成 ==========\n')
|
print(f'[轮询] ========== 初始化完成 ==========\n')
|
||||||
|
|
||||||
# 创建后台调度器
|
# 检测是否在 eventlet 环境下运行
|
||||||
|
is_eventlet = False
|
||||||
|
try:
|
||||||
|
import eventlet
|
||||||
|
# 检查 eventlet 是否已经 monkey patch
|
||||||
|
if hasattr(eventlet, 'patcher') and eventlet.patcher.is_monkey_patched('socket'):
|
||||||
|
is_eventlet = True
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if is_eventlet:
|
||||||
|
# Eventlet 环境:使用 eventlet 的协程定时器
|
||||||
|
print(f'[轮询] 检测到 Eventlet 环境,使用 eventlet 协程调度器')
|
||||||
|
|
||||||
|
def eventlet_polling_loop():
|
||||||
|
"""Eventlet 兼容的轮询循环"""
|
||||||
|
import eventlet
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
eventlet.sleep(30) # 等待 30 秒
|
||||||
|
poll_new_events()
|
||||||
|
except Exception as e:
|
||||||
|
print(f'[轮询 ERROR] Eventlet 轮询循环出错: {e}')
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
eventlet.sleep(30) # 出错后等待 30 秒再继续
|
||||||
|
|
||||||
|
# 启动 eventlet 协程
|
||||||
|
eventlet.spawn(eventlet_polling_loop)
|
||||||
|
print(f'[轮询] Eventlet 协程调度器已启动 (PID: {os.getpid()}),每 30 秒检查一次新事件')
|
||||||
|
else:
|
||||||
|
# 非 Eventlet 环境:使用 APScheduler
|
||||||
|
print(f'[轮询] 使用 APScheduler BackgroundScheduler')
|
||||||
scheduler = BackgroundScheduler()
|
scheduler = BackgroundScheduler()
|
||||||
# 每 30 秒执行一次轮询
|
# 每 30 秒执行一次轮询
|
||||||
scheduler.add_job(
|
scheduler.add_job(
|
||||||
@@ -11694,7 +11726,7 @@ def initialize_event_polling():
|
|||||||
replace_existing=True
|
replace_existing=True
|
||||||
)
|
)
|
||||||
scheduler.start()
|
scheduler.start()
|
||||||
print(f'[轮询] 调度器已启动 (PID: {os.getpid()}),每 30 秒检查一次新事件')
|
print(f'[轮询] APScheduler 调度器已启动 (PID: {os.getpid()}),每 30 秒检查一次新事件')
|
||||||
|
|
||||||
_polling_initialized = True
|
_polling_initialized = True
|
||||||
|
|
||||||
|
|||||||
@@ -135,6 +135,14 @@ def post_worker_init(worker):
|
|||||||
"""Worker 初始化完成后调用"""
|
"""Worker 初始化完成后调用"""
|
||||||
print(f"✅ Eventlet Worker {worker.pid} 已初始化 (10,000 并发连接就绪)")
|
print(f"✅ Eventlet Worker {worker.pid} 已初始化 (10,000 并发连接就绪)")
|
||||||
|
|
||||||
|
# 触发事件轮询初始化(使用 Redis 锁确保只有一个 Worker 启动调度器)
|
||||||
|
try:
|
||||||
|
from app import _auto_init_polling
|
||||||
|
print(f"[轮询] Worker {worker.pid} 尝试初始化事件轮询...")
|
||||||
|
_auto_init_polling()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[轮询] Worker {worker.pid} 初始化事件轮询失败: {e}")
|
||||||
|
|
||||||
|
|
||||||
def worker_abort(worker):
|
def worker_abort(worker):
|
||||||
"""Worker 收到 SIGABRT 信号时调用(超时)"""
|
"""Worker 收到 SIGABRT 信号时调用(超时)"""
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 871 KiB |
BIN
public/images/services/wechat_app2.jpg
Normal file
BIN
public/images/services/wechat_app2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
public/images/services/wechat_group.png
Normal file
BIN
public/images/services/wechat_group.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 158 KiB |
@@ -18,6 +18,7 @@ import {
|
|||||||
Link,
|
Link,
|
||||||
Divider,
|
Divider,
|
||||||
Avatar,
|
Avatar,
|
||||||
|
Image,
|
||||||
useColorModeValue
|
useColorModeValue
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { useNavigate, useLocation } from 'react-router-dom';
|
import { useNavigate, useLocation } from 'react-router-dom';
|
||||||
@@ -282,7 +283,55 @@ const MobileDrawer = memo(({
|
|||||||
{/* 联系我们 */}
|
{/* 联系我们 */}
|
||||||
<Box>
|
<Box>
|
||||||
<Text fontWeight="bold" mb={2}>联系我们</Text>
|
<Text fontWeight="bold" mb={2}>联系我们</Text>
|
||||||
<Text fontSize="sm" color={contactTextColor}>敬请期待</Text>
|
<Text fontSize="xs" color={contactTextColor} mb={3}>
|
||||||
|
扫码添加,获取更多资讯
|
||||||
|
</Text>
|
||||||
|
<HStack spacing={3} justify="center">
|
||||||
|
{/* 微信群二维码 */}
|
||||||
|
<VStack spacing={1}>
|
||||||
|
<Box
|
||||||
|
borderRadius="md"
|
||||||
|
overflow="hidden"
|
||||||
|
boxShadow="sm"
|
||||||
|
border="1px solid"
|
||||||
|
borderColor="gray.200"
|
||||||
|
p={1.5}
|
||||||
|
bg="white"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src="/images/services/wechat_group.png"
|
||||||
|
alt="微信群"
|
||||||
|
boxSize="90px"
|
||||||
|
objectFit="contain"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Text fontSize="xs" color={contactTextColor}>
|
||||||
|
微信交流群
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
{/* 小程序二维码 */}
|
||||||
|
<VStack spacing={1}>
|
||||||
|
<Box
|
||||||
|
borderRadius="md"
|
||||||
|
overflow="hidden"
|
||||||
|
boxShadow="sm"
|
||||||
|
border="1px solid"
|
||||||
|
borderColor="gray.200"
|
||||||
|
p={1.5}
|
||||||
|
bg="white"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src="/images/services/wechat_app2.jpg"
|
||||||
|
alt="小程序"
|
||||||
|
boxSize="90px"
|
||||||
|
objectFit="contain"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Text fontSize="xs" color={contactTextColor}>
|
||||||
|
微信小程序
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
</HStack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* 移动端登录/登出按钮 */}
|
{/* 移动端登录/登出按钮 */}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
import React, { memo, useCallback } from 'react';
|
import React, { memo, useCallback } from 'react';
|
||||||
import {
|
import {
|
||||||
HStack,
|
HStack,
|
||||||
|
VStack,
|
||||||
Menu,
|
Menu,
|
||||||
MenuButton,
|
MenuButton,
|
||||||
MenuList,
|
MenuList,
|
||||||
@@ -12,6 +13,8 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
Flex,
|
Flex,
|
||||||
Badge,
|
Badge,
|
||||||
|
Image,
|
||||||
|
Box,
|
||||||
useColorModeValue
|
useColorModeValue
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { ChevronDownIcon } from '@chakra-ui/icons';
|
import { ChevronDownIcon } from '@chakra-ui/icons';
|
||||||
@@ -279,12 +282,64 @@ const DesktopNav = memo(({ isAuthenticated, user }) => {
|
|||||||
联系我们
|
联系我们
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
<MenuList
|
<MenuList
|
||||||
minW="260px"
|
minW="340px"
|
||||||
p={4}
|
p={4}
|
||||||
onMouseEnter={contactUsMenu.handleMouseEnter}
|
onMouseEnter={contactUsMenu.handleMouseEnter}
|
||||||
onMouseLeave={contactUsMenu.handleMouseLeave}
|
onMouseLeave={contactUsMenu.handleMouseLeave}
|
||||||
>
|
>
|
||||||
<Text fontSize="sm" color={contactTextColor}>敬请期待</Text>
|
<Text fontSize="sm" fontWeight="bold" mb={3} color={contactTextColor}>
|
||||||
|
扫码添加,获取更多资讯
|
||||||
|
</Text>
|
||||||
|
<HStack spacing={4} justify="center">
|
||||||
|
{/* 微信群二维码 */}
|
||||||
|
<VStack spacing={2}>
|
||||||
|
<Box
|
||||||
|
borderRadius="lg"
|
||||||
|
overflow="hidden"
|
||||||
|
boxShadow="sm"
|
||||||
|
border="1px solid"
|
||||||
|
borderColor="gray.200"
|
||||||
|
p={2}
|
||||||
|
bg="white"
|
||||||
|
_hover={{ boxShadow: 'md', transform: 'scale(1.02)' }}
|
||||||
|
transition="all 0.2s"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src="/images/services/wechat_group.png"
|
||||||
|
alt="微信群"
|
||||||
|
boxSize="120px"
|
||||||
|
objectFit="contain"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Text fontSize="xs" color={contactTextColor} fontWeight="medium">
|
||||||
|
微信交流群
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
{/* 小程序二维码 */}
|
||||||
|
<VStack spacing={2}>
|
||||||
|
<Box
|
||||||
|
borderRadius="lg"
|
||||||
|
overflow="hidden"
|
||||||
|
boxShadow="sm"
|
||||||
|
border="1px solid"
|
||||||
|
borderColor="gray.200"
|
||||||
|
p={2}
|
||||||
|
bg="white"
|
||||||
|
_hover={{ boxShadow: 'md', transform: 'scale(1.02)' }}
|
||||||
|
transition="all 0.2s"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src="/images/services/wechat_app2.jpg"
|
||||||
|
alt="小程序"
|
||||||
|
boxSize="120px"
|
||||||
|
objectFit="contain"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Text fontSize="xs" color={contactTextColor} fontWeight="medium">
|
||||||
|
微信小程序
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
</HStack>
|
||||||
</MenuList>
|
</MenuList>
|
||||||
</Menu>
|
</Menu>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|||||||
Reference in New Issue
Block a user