tuoheng_algN/concurrency/Pull2PushStreamProcess.py

154 lines
8.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
import time
from traceback import format_exc
from multiprocessing import Process, Queue
from loguru import logger
from concurrency.Pull2PushStreamThread import PushSteamThread
from enums.StatusEnum import PushStreamStatus, ExecuteStatus
from util.LogUtils import init_log
from enums.ExceptionEnum import ExceptionType
from entity.FeedBack import pull_stream_feedback
from exception.CustomerException import ServiceException
from util.QueUtil import get_no_block_queue, put_queue
class PushStreamProcess(Process):
__slots__ = ('_fb_queue', 'event_queue', '_context', '_msg', '_analysisType')
def __init__(self, *args):
super().__init__()
self._fb_queue, self._context, self._msg, self._analysisType = args
self.event_queue = Queue()
def sendEvent(self, eBody):
try:
self.event_queue.put(eBody, timeout=2)
except Exception:
logger.error("添加事件到队列超时异常:{}, requestId:{}", format_exc(), self._msg["request_id"])
raise ServiceException(ExceptionType.SERVICE_INNER_EXCEPTION.value[0],
ExceptionType.SERVICE_INNER_EXCEPTION.value[1])
def run(self):
msg, context = self._msg, self._context
requestId, videoUrls = msg["request_id"], msg["video_urls"]
base_dir, env = context['base_dir'], context['env']
fb_queue = self._fb_queue
task, videoStatus = {}, {}
ex = None
try:
init_log(base_dir, env)
if videoUrls is None or len(videoUrls) == 0:
raise ServiceException(ExceptionType.PUSH_STREAM_URL_IS_NULL.value[0],
ExceptionType.PUSH_STREAM_URL_IS_NULL.value[1])
if len(videoUrls) > 5:
logger.error("推流数量超过限制, 当前推流数量: {}, requestId:{}", len(videoUrls), requestId)
raise ServiceException(ExceptionType.PULL_STREAM_NUM_LIMIT_EXCEPTION.value[0],
ExceptionType.PULL_STREAM_NUM_LIMIT_EXCEPTION.value[1])
videoInfo = [{"id": url["id"], "status": PushStreamStatus.WAITING.value[0]} for url in videoUrls if
url.get("id")]
put_queue(fb_queue, pull_stream_feedback(requestId, ExecuteStatus.WAITING.value[0], "", "", videoInfo))
for videoUrl in videoUrls:
pushThread = PushSteamThread(videoUrl["pull_url"], videoUrl["push_url"], requestId, videoUrl["id"])
pushThread.start()
task[videoUrl["id"]] = pushThread
enable_time = time.time()
for video in videoInfo:
videoStatus[video.get("id")] = video.get("status")
count = 0
while True:
# 整个推流任务超时时间
if time.time() - enable_time > 43200:
logger.error("任务执行超时, requestId:{}", requestId)
for t in list(task.keys()):
if task[t].is_alive():
task[t].status = False
task[t].pushStreamUtil.close_push_stream_sp()
task[t].join(120)
videoStatus[t] = PushStreamStatus.TIMEOUT.value[0]
videoInfo_timeout = [{"id": k, "status": v} for k, v in videoStatus.items()]
put_queue(fb_queue, pull_stream_feedback(requestId, ExecuteStatus.TIMEOUT.value[0],
ExceptionType.TASK_EXCUTE_TIMEOUT.value[0],
ExceptionType.TASK_EXCUTE_TIMEOUT.value[1],
videoInfo_timeout))
break
# 接受停止指令
event_result = get_no_block_queue(self.event_queue)
if event_result is not None:
command = event_result.get("command")
videoIds = event_result.get("videoIds")
if "stop" == command:
# 如果videoIds是空停止所有任务
if videoIds is None or len(videoIds) == 0:
logger.info("停止所有执行的推流任务, requestId:{}", requestId)
for t in list(task.keys()):
if task[t].is_alive():
task[t].status = False
task[t].pushStreamUtil.close_push_stream_sp()
task[t].join(120)
videoStatus[t] = PushStreamStatus.SUCCESS.value[0]
videoInfo_sucess = [{"id": k, "status": v} for k, v in videoStatus.items()]
put_queue(fb_queue, pull_stream_feedback(requestId, ExecuteStatus.SUCCESS.value[0], "", "",
videoInfo_sucess))
break
else:
logger.info("停止指定的推流任务, requestId:{}", requestId)
alive_thread = 0
for t in list(task.keys()):
if task[t].is_alive():
if t in videoIds:
task[t].status = False
task[t].pushStreamUtil.close_push_stream_sp()
task[t].join(120)
videoStatus[t] = PushStreamStatus.SUCCESS.value[0]
else:
alive_thread += 1
if alive_thread == 0:
videoInfo_sucess = [{"id": k, "status": v} for k, v in videoStatus.items()]
put_queue(fb_queue, pull_stream_feedback(requestId, ExecuteStatus.SUCCESS.value[0], "",
"", videoInfo_sucess))
break
for t in list(task.keys()):
if task[t].status and not task[t].is_alive():
videoStatus[t] = PushStreamStatus.FAILED.value[0]
logger.error("检测到推流线程异常停止videoId:{}, requestId:{}", t, requestId)
if task[t].ex:
raise task[t].ex
raise Exception("检测到推流线程异常停止!")
if task[t].is_alive():
videoStatus[t] = task[t].excute_status
if count % 10 == 0:
videoInfo_hb = [{"id": k, "status": v} for k, v in videoStatus.items()]
put_queue(fb_queue, pull_stream_feedback(requestId, ExecuteStatus.RUNNING.value[0], "", "",
videoInfo_hb))
count = 0
count += 1
time.sleep(1)
except ServiceException as s:
ex = s.code, s.msg
logger.error("服务异常,异常编号:{}, 异常描述:{}, requestId: {}", s.code, s.msg, requestId)
except Exception:
ex = ExceptionType.SERVICE_INNER_EXCEPTION.value[0], ExceptionType.SERVICE_INNER_EXCEPTION.value[1]
logger.error("服务异常: {}, requestId: {},", format_exc(), requestId)
finally:
if ex:
errorCode, errorMsg = ex
for t in list(task.keys()):
if task[t].is_alive():
task[t].status = False
task[t].pushStreamUtil.close_push_stream_sp()
task[t].join(120)
videoStatus[t] = PushStreamStatus.FAILED.value[0]
videoInfo_ex = [{"id": k, "status": v} for k, v in videoStatus.items()]
put_queue(fb_queue, pull_stream_feedback(requestId, ExecuteStatus.FAILED.value[0], errorCode, errorMsg,
videoInfo_ex))
for t in list(task.keys()):
if task[t].is_alive():
task[t].status = False
task[t].pushStreamUtil.close_push_stream_sp()
task[t].join(120)
logger.info("推流任务完成, requestId: {}", requestId)