微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

WinError 10038 和可能执行不力的任务循环超时? (discord.py 的东西也是) 在这里编码的菜鸟

如何解决WinError 10038 和可能执行不力的任务循环超时? (discord.py 的东西也是) 在这里编码的菜鸟

我才 3 周多就开始自学 Python,所以请耐心等待 :')

我有一个任务循环,在机器人运行时无限期地每 5 秒运行一次,机器人运行使用名为“cogs”的模块的“RED discord bot”框架,这是我一直在研究的部分,这是部分我的代码一直有问题:

    # Crosschat loop logic
    @tasks.loop(seconds=3)
    async def getchat(self):
        data = await self.config.all_guilds()
        for guildID in data:
            guild = self.bot.get_guild(int(guildID))
            if not guild:
                continue
            guildsettings = await self.config.guild(guild).clusters()
            if not guildsettings:
                continue

            for cluster in guildsettings:
                if not guildsettings[cluster]:
                    continue
                globalchat = guildsettings[cluster]["globalchatchannel"]
                for server in guildsettings[cluster]["servers"]:
                    guildsettings[cluster]["servers"][server]["cluster"] = cluster
                    guildsettings[cluster]["servers"][server]["globalchat"] = globalchat
                    if not guildsettings[cluster]["servers"][server]["chatchannel"]:
                        return
                    channel = guild.get_channel(int(guildsettings[cluster]["servers"][server]["chatchannel"]))
                    if not channel:
                        return

                    """Loop option #1 using discord.ext.tasks"""
                    # await self.getchatrcon(guild,#                        guildsettings[cluster]["servers"][server]["cluster"],#                        guildsettings[cluster]["servers"][server]
                    #                        )

                    """Loop option #2 using asyncio task loop"""
                    chattask = []
                    chattask.append(self.getchatrcon(guild,guildsettings[cluster]["servers"][server]["cluster"],guildsettings[cluster]["servers"][server]
                                                  ))

                    # Gathers the getchat tasks with a timeout
                    try:
                        tasks = asyncio.gather(*chattask)
                        if len(asyncio.all_tasks()) > 60:
                            print(f"Task list full{len(asyncio.all_tasks())},skipping iteration")
                            return
                        await asyncio.wait_for(tasks,timeout=2)
                    except asyncio.TimeoutError as e:
                        print(f"task timeout: {e}")
                        await asyncio.sleep(5)

    # Rcon function for getchat loop,parses the response to send to designated discord channels.
    async def getchatrcon(self,guild,cluster,server):
        guildsettings = await self.config.guild(guild).clusters()
        adminlogchannel = guild.get_channel(int(guildsettings[cluster]["adminlogchannel"]))
        globalchat = guild.get_channel(int(server["globalchat"]))
        chatchannel = guild.get_channel(int(server["chatchannel"]))

        try:
            res = await rcon.asyncio.rcon(
                command="getchat",host=server['ip'],port=server['port'],passwd=server['password']
            )
        except OSError as e:
            if e.osrror == 121:
                return await asyncio.sleep(30)
            if e.osrror == 10038:
                return await asyncio.sleep(60)


        if "Server received,But no response!!" in res:
            return
        msgs = res.split("\n")
        filteredmsg = []
        for msg in msgs:
            if msg.startswith("AdminCmd:"):
                adminmsg = msg
                await adminlogchannel.send(f"**{server['name'].capitalize()}**\n{Box(adminmsg,lang='python')}")
            if "): " not in msg:
                continue
            if "tribe" and ",ID" in msg.lower():
                continue  # Add more features at a later date for tribe log channels
            else:
                if msg not in ['',' ','Server received,But no response!! ']:
                    if not msg.startswith('SERVER:'):
                        filteredmsg.append(msg)
        for msg in filteredmsg:
            await globalchat.send(f"{chatchannel.mention}: {msg}")
            await chatchannel.send(msg)


    # Just waits till bot is ready to do the chat loop
    @getchat.before_loop
    async def before_getchat(self):
        print("Getting crosschat loop ready.")
        await self.bot.wait_until_red_ready()

这段代码的作用是在所有服务器上使用“getchat”命令,并将消息返回到我为它来自的指定服务器设置的频道。 代码在运行的第一个小时左右运行良好,但是我收到“WinError 10038”,一段时间后开始向控制台发送垃圾邮件

[07:28:46] CRITICAL Caught unhandled exception in event loop:                                                [red.main]
                    Exception in callback _ProactorBasePipeTransport._call_connection_lost(None)
┌───────────────────────────────────────── Traceback (most recent call last) ─────────────────────────────────────────┐
│ C:\python38\lib\asyncio\events.py:81 in _run                                                                        │
│ >  81             self._context.run(self._callback,*self._args)                                                    │
│ C:\python38\lib\asyncio\proactor_events.py:162 in _call_connection_lost                                             │
│ > 162                 self._sock.shutdown(socket.SHUT_RDWR)                                                         │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
OSError: [WinError 10038] An operation was attempted on something that is not a socket

我注意到当我重新启动机器人时,控制台会被这个 RuntimeError 淹没数百次:

RuntimeError: Event loop is closed
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000002EE9F655E50>
Traceback (most recent call last):
  File "C:\python38\lib\asyncio\proactor_events.py",line 116,in __del__
    self.close()
  File "C:\python38\lib\asyncio\proactor_events.py",line 108,in close
    self._loop.call_soon(self._call_connection_lost,None)
  File "C:\python38\lib\asyncio\base_events.py",line 719,in call_soon
    self._check_closed()
  File "C:\python38\lib\asyncio\base_events.py",line 508,in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

我的问题/顾虑/理论: 在开始向 WinError 发送垃圾邮件之前,cog 可以正常工作大约一个小时,而在机器人重启时发送的大量 RuntimeError: Event loop is closed 使我认为这是任务循环列表中的任务过多,可能使机器人不堪重负。>

我的问题是:

WinError 是否可能是由于我的“chattask”任务循环列表被附加任务溢出?

我是否正确实施了我尝试包含的超时?

有没有更好的方法来完成这个任务循环?

机器人运行的操作系统是 Windows 10,我还在代码中指定了以下事件循环策略:asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

我将此库用于 RCON 协议:https://pypi.org/project/rcon/

我希望我能很好地澄清我的问题,感谢任何能发现我一些指针并握住我手的人总是很感激,学习 py 一直是一个反复试验的潘多拉盒子,但到目前为止超级有趣!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?