Files
biliup/work.py
T
2018-03-15 23:18:04 +08:00

178 lines
6.8 KiB
Python
Raw 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.
import logging
import signal
from logging.handlers import TimedRotatingFileHandler
from multiprocessing import Process
import time
import os
import errno
import psutil
# log_fmt = '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s'
# formatter = logging.Formatter(log_fmt)
# log_file_handler = TimedRotatingFileHandler(filename="ds_update.log", when="D", interval=1, backupCount=2)
# # log_file_handler.suffix = "%Y-%m-%d.log"
# # log_file_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}.log$")
# log_file_handler.setFormatter(formatter)
# logging.basicConfig(level=logging.INFO)
# logger = logging.getLogger(__name__)
# logger.addHandler(log_file_handler)
logger = logging.getLogger('log01')
def wait_child(signum, frame):
logger.debug('receive SIGCHLD')
try:
while True:
# -1 表示任意子进程
# os.WNOHANG 表示如果没有可用的需要 wait 退出状态的子进程,立即返回不阻塞
cpid, status = os.waitpid(-1, os.WNOHANG)
if cpid == 0:
logger.debug('no child process was immediately available')
break
exitcode = status >> 8
logger.debug('child process %s exit with exitcode %s', cpid, exitcode)
except OSError as e:
if e.errno == errno.ECHILD:
logger.error('current process has no existing unwaited-for child processes.')
else:
raise
logger.debug('handle SIGCHLD end')
def kill_child_processes(parent_pid, file_name_, sig=signal.SIGINT):
file_name_ = file_name_ + '.part'
last_file_size = 0.0
while True:
time.sleep(15)
if os.path.isfile(file_name_):
file_size = os.path.getsize(file_name_) / 1024 / 1024 / 1024
file_sizes = os.path.getsize(file_name_)
if float(file_sizes) == last_file_size:
try:
parent = psutil.Process(parent_pid)
except psutil.NoSuchProcess:
return
children = parent.children(recursive=True)
if len(children) == 0:
parent.send_signal(sig)
logger.info('下载卡死pandaTV' + file_name_)
else:
for process in children:
# print(process)
process.send_signal(sig)
logger.info('下载卡死' + file_name_)
# time.sleep(1)
if os.path.isfile(file_name_):
logger.info('卡死下载进程可能未成功退出')
continue
else:
logger.info('卡死下载进程成功退出')
break
last_file_size = file_sizes
if float(file_size) >= 3.5:
try:
parent = psutil.Process(parent_pid)
except psutil.NoSuchProcess:
return
children = parent.children(recursive=True)
if len(children) == 0:
parent.send_signal(sig)
logger.info('分段下载pandatv' + file_name_)
else:
for process in children:
# print(process)
process.send_signal(sig)
print('分段下载twitch')
logger.info('分段下载twitch' + file_name_)
break
else:
logger.info('退出监控进程')
return
# os._exit(0)
logger.info('退出监控进程')
def monitoring(q):
signal.signal(signal.SIGCHLD, wait_child)
while True:
# print('开始监测')
pid, file_name = q.get()
time.sleep(5)
logger.info('获取到{0},{1}'.format(pid,file_name))
p = Process(target=kill_child_processes, args=(pid, file_name))
p.start()
def new_hook(t, v, tb):
logger.error("Uncaught exception:", exc_info=(t, v, tb))
class SafeRotatingFileHandler(TimedRotatingFileHandler):
def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False):
TimedRotatingFileHandler.__init__(self, filename, when, interval, backupCount, encoding, delay, utc)
"""
Override doRollover
lines commanded by "##" is changed by cc
"""
def doRollover(self):
"""
do a rollover; in this case, a date/time stamp is appended to the filename
when the rollover happens. However, you want the file to be named for the
start of the interval, not the current time. If there is a backup count,
then we have to get a list of matching filenames, sort them and remove
the one with the oldest suffix.
Override, 1. if dfn not exist then do rename
2. _open with "a" model
"""
if self.stream:
self.stream.close()
self.stream = None
# get the time that this sequence started at and make it a TimeTuple
currentTime = int(time.time())
dstNow = time.localtime(currentTime)[-1]
t = self.rolloverAt - self.interval
if self.utc:
timeTuple = time.gmtime(t)
else:
timeTuple = time.localtime(t)
dstThen = timeTuple[-1]
if dstNow != dstThen:
if dstNow:
addend = 3600
else:
addend = -3600
timeTuple = time.localtime(t + addend)
dfn = self.baseFilename + "." + time.strftime(self.suffix, timeTuple)
## if os.path.exists(dfn):
## os.remove(dfn)
# Issue 18940: A file may not have been created if delay is True.
## if os.path.exists(self.baseFilename):
if not os.path.exists(dfn) and os.path.exists(self.baseFilename):
os.rename(self.baseFilename, dfn)
if self.backupCount > 0:
for s in self.getFilesToDelete():
os.remove(s)
if not self.delay:
self.mode = "a"
self.stream = self._open()
newRolloverAt = self.computeRollover(currentTime)
while newRolloverAt <= currentTime:
newRolloverAt = newRolloverAt + self.interval
# If DST changes and midnight or weekly rollover, adjust for this.
if (self.when == 'MIDNIGHT' or self.when.startswith('W')) and not self.utc:
dstAtRollover = time.localtime(newRolloverAt)[-1]
if dstNow != dstAtRollover:
if not dstNow: # DST kicks in before next rollover, so we need to deduct an hour
addend = -3600
else: # DST bows out before next rollover, so we need to add an hour
addend = 3600
newRolloverAt += addend
self.rolloverAt = newRolloverAt