Python Websocket 模块继续启动未被杀死的进程,导致内存问题

标签 python websocket

我有一个在用于分割音频文件的服务器上运行的代码。我使用 websockets 来触发浏览器的这个过程。

问题是,这个分割过程的每个触发器都会创建 10 个新的 python 进程,这些进程不会被杀死,从而在运行一段时间后导致内存错误。 我不明白为什么创建这些进程以及如何改进脚本。 现在我正在使用一种黑客方法,每天运行一次 cron 作业,杀死任何剩余的进程。 任何有关这些进程的作用或创建它们的原因以及如何在脚本运行后自动终止它们的指示都会很棒。

在这里您可以看到每次运行 split 函数时创建的进程: Unidentified Websocket Process

代码:

#!/usr/bin/env python


import websockets
#import aiohttp
import asyncio
from pathlib import Path
from io import BytesIO
from spleeter.separator import Separator
import sys
import tempfile
import os
from zipfile import ZipFile

async def split(websocket, path):
    print("split started")
    stems = await websocket.recv()
    audioFormat = await websocket.recv()
    bitRate = await websocket.recv()
    audio_bytes = await websocket.recv()
    separator = Separator('spleeter:'+stems+'stems')
    temp, pathname = tempfile.mkstemp()
    file_paths = []
    p = Path('/tmp/filename/'+str(pathname).split('/')[2])
    if not (os.path.exists(p)):
        print('New Path')
        with open(pathname, mode='wb') as f:
            f.write(audio_bytes)
            print('Writing to file ' + str(f) + 'with seperator: ' + str(separator))
        if audioFormat == "mp3":
            print("mp3")
            separator.separate_to_file(pathname, "/tmp/filename", codec="mp3", bitrate=bitRate)
        else:
            print("wav")
            separator.separate_to_file(pathname, "/tmp/filename")
        separator.join()
        print('Separating finished')
    oldwd = os.getcwd()
    os.chdir(p)
    for entry in os.scandir(path='.'):
        print('Appending file: ' + str(entry))
        if entry.is_file():
            file_paths.append(entry)
    with ZipFile(p / 'files.zip','w') as zip:
        for f in file_paths:
            zip.write(f)
    print('Zip created')
    os.chdir(oldwd)
    
    f=open(p / 'files.zip', "rb")
    contents = f.read()
    await websocket.send(contents)

    print('Zip sent to client')

async def main():
    print("main called")
    async with websockets.serve(
        split,
        # "0.0.0.0",
        "localhost",
        9014,
        max_size = None, 
        create_protocol=websockets.basic_auth_protocol_factory(
                realm="my dev server",
                credentials=("TEST", "CREDS"),
            )
        ):
            await asyncio.Future() # run forever

asyncio.run(main())

最佳答案

我遇到了类似的内存泄漏问题,问题是客户端永远不会关闭连接,因此每次客户端连接时,都会打开一个新的 websocket 并永远卡在内存中,等待接收更多消息。

就我而言,我知道套接字连接的生命周期应该不到一分钟,并且可以安全地假设一分钟后同一套接字连接内不会再收到任何消息,所以我设置了 60 秒的超时。

请注意,当您设置超时时,它会引发超时异常,因此您需要处理该异常。

所以代替:

data = wait websocket.recv()

我用过:

data = wait asyncio.wait_for(websocket.recv(), timeout=60)

super 简化的代码来说明:

import asyncio
import websockets

async def handler(websocket):
    try:
        # Added a timeout so it wouldn't wait indefinitely
        await asyncio.wait_for(websocket.recv(), timeout=60)
        # do some work...
    except websockets.exceptions.ConnectionClosed:
        print("Client disconnected")
    finally:
        # Unregister.
        print("Unregistering websocket")

关于Python Websocket 模块继续启动未被杀死的进程,导致内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69801985/

相关文章:

python - 使用 python 读取优化 cassandra

python - 将转换器与 read_csv 一起使用时获取错误行

websocket - 通过对 websockets 的多个引用向客户端发送消息

node.js - 使用WebSockets(ws)连接到Rcon

wcf - 使用 WCF(或类似)将通知从服务器推送到客户端

python - 导入错误 : TensorBoard

python——在列表上应用 lstrip 的递归列表理解

node.js - 哪些基于 WebSocket 的库可以与 React Native 一起使用?

java - Lambda 在 Websocket session 中不起作用

python - 我如何抵消 Pandas dayofyear 以便开始日期是 10 月 1 日而不是 1 月 1 日?