不和谐python中的任务循环问题

时间:2020-03-08 15:53:44

标签: python loops bots discord.py

我正在用python构建一个Discord机器人,但是在使用任务循环时遇到了一些麻烦: 僵尸程序在没有任何特定事件的几次循环后就被击倒。

client = discord.Client()

@tasks.loop(seconds=120)
async def checking_game():
    await client.wait_until_ready()
    try:
        if checking_game.current_loop==0:
            await asyncio.sleep(15)
        date_actual = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        print("{} : Initializing...".format(date_actual))
        count_league=0
        list_leagues = dbconnect.get_list_leagues_parsed(DB_local)
        for league in list_leagues:
            count_league = count_league+1
            matchs_in_DB = new_matchs = 0
            skiprange=0
            list_games = list_games_parsed = []
            league_id = league[0]
            league_name = league[1]

            finish = False
            while finish == False:
                c, conn = dbconnect.connection(DB_local)
                c.execute("SELECT match_id, 1_is_parsed FROM games_acquired WHERE league_id = (%s)", (league_id,))
                resultset = c.fetchall()
                #if resultset != None:
                for result in resultset:
                    list_games.append(result[0])
                    if result[1]==1:
                        list_games_parsed.append(result[0])

                url = 'https://api.stratz.com/api/v1/league/' + str(league_id) + '/matches?&take=250' + '&skip=' + str(skiprange)
                jsonleague = utilitary.JSONRequester(url)
                for match in jsonleague:
                    match_id = match['id']
                    if match_id in list_games:
                        matchs_in_DB = matchs_in_DB+1
                        continue
                    else :
                        new_matchs = new_matchs+1
                        date_update = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                        parsed = avoid = count_records = 0
                        insert = ("INSERT into games_acquired (match_id, league_id, date, 1_is_parsed, 1_is_avoid, count_records)""VALUES (%s, %s, %s, %s, %s, %s)")
                        data = (match_id, league_id, date_update, parsed, avoid, count_records)
                        dbconnect.insertToTable(DB_local, insert, data)
                        #print("{} added to DB.".format(match_id))
                    if match_id in list_games_parsed:
                        #print("{} allready parsed.".format(match_id))
                        continue
                    else:
                        functions.check_game_ready_opendota(match_id)
                        #print("parsing {}".format(match_id))
                        #functions.parser_game(DB_ftv, DB_local, match_id)
                        print("creating img PG {}".format(match_id))
                        urlOpendota = "https://api.opendota.com/api/matches/"+str(match_id)
                        jsonTeamOpendota =utilitary.JSONRequester(urlOpendota)
                        success, image_post_game = image_generator.generate_post_game(jsonTeamOpendota, match_id)
                        logging.info(f"Send new postmatch Image {match_id}")
                        c, conn = dbconnect.connection(DB_local)
                        c.execute("UPDATE games_acquired SET 1_is_parsed = 1 WHERE match_id = (%s)", (match_id,))
                        if success ==1:
                            try:
                                #print("send img")

                                await insa_chan.send(file=discord.File(image_post_game))
                            except Exception as e:
                                print(e)
                print("{} allready in DB | {} new matchs added".format(matchs_in_DB, new_matchs))
                if len(jsonleague) == 250:
                    skiprange = skiprange +250
                else:
                    #print(f'{league_name} completly added ({count_league}/{len(setup.list_leagues)}) !')
                    finish = True
        date_actual = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        print("{} : Loop finished : {} tickets checked".format(date_actual, len(list_leagues)))
    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print(exc_type, fname, exc_tb.tb_lineno)

api的任务循环检查结果,如果有新结果,则使用此新统计信息构建映像,然后将该映像作为文件发布到不和谐频道中。 调用该函数以生成图像是好的,并且不承担任何麻烦。

其余代码为:

@client.event
async def on_ready():
    for guild in client.guilds:
        if guild.name == setup.GUILD:
            break

    print(
        f'{client.user} is connected to the following guild:\n'
        f'{guild.name}(id: {guild.id})')
    logging.info(setup.GUILD)

    global insa_chan
    insa_chan = discord.utils.get(client.get_all_channels(), guild__name=setup.GUILD, name=insalan_channel)
    global general_chan
    general_chan = discord.utils.get(client.get_all_channels(), guild__name=setup.GUILD, name=general_channel)
    #print(f'{admin_chan.name}(id: {admin_chan.id})')

    checking_game.start()

@client.event
async def on_message(message):
    try:
        if not message.author.id == bot_id and type(message.channel) == discord.channel.DMChannel:
            check_auth(message)
            chan = message.channel
            command = '!game'
            ms = str(str.lower(message.content))
            if ms.startswith(command):
                print(ms)
                game_id = ms[len(command):]
                game_id = game_id.replace(' ','')
                print(game_id)
                try:
                    game_id = int(game_id)
                except:
                    await chan.send("Oups! Je n'ai pas réussi à synthétiser cette game : {}. \n Erreur dans l'ID".format(str(game_id)))
                    return
                print(game_id)
                ask_urlOpendota = "https://api.opendota.com/api/matches/"+str(game_id)
                ask_jsonTeamOpendota =utilitary.JSONRequester(ask_urlOpendota)
                success, ask_image_post_game = image_generator.generate_post_game(ask_jsonTeamOpendota, game_id)
                if success==1:
                    #print('printing message to {} : {}'.format(message.author.name, message.content))
                    #await general_chan.send(message.content)
                    await chan.send(file=discord.File(ask_image_post_game))
                else:
                    await chan.send("Oups! Je n'ai pas réussi à synthétiser cette game : {}".format(str(game_id)))
    except Exception as e:
        print('Error in on_message: {}'.format(e))



if __name__ == "__main__":
    try:
        client.run(TOKEN)
    except Exception as e:
        print('Error in __main__: {}'.format(e))

我看到了一些有关client.loop.create_task(checking_game())的教程,但出现错误“无法调用'Loop'对象”

如果我不写这个,那么在连接机器人之前,任务循环“ cheking_game”也开始运行:

if checking_game.current_loop==0:
    await asyncio.sleep(15)

功能 client.wait_until_ready()似乎无效。

有人可以告诉我我哪里错了,并帮助我解决这个问题吗?

感谢您的阅读! 如果您需要有关代码或用法的更多信息,请告诉我

编辑: 关闭时,我会记录以下错误:

2020-03-08 23:39:16,440 discord.gateway    WARNING Heartbeat blocked for more than 5 seconds.
2020-03-08 23:41:41,900  discord.client       INFO Cleaning up tasks.
2020-03-08 23:41:41,901  discord.client       INFO Cleaning up after 2 tasks.
2020-03-08 23:41:41,901  discord.client       INFO All tasks finished cancelling.
2020-03-08 23:41:41,902  discord.client       INFO Closing the event loop.

0 个答案:

没有答案