我正在用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.