python - 托管在 Heroku 上的 Python discord 应用程序有时会挂起,没有输出/异常
问题描述
我有一个不和谐的机器人,它向 Reddit API 发出请求。现在,我将其设置为每分钟发出 1 个请求以进行测试。
这段代码运行得很好,直到它在某个时间点停止记录到 Heroku 日志,从那时起,无论我做什么(重置测功机,再次部署)它都不会运行预定的作业,它只是挂起没有输出到日志。
主文件:
僵尸软件
import os
import discord
from discord.ext import commands
from dotenv import load_dotenv
from db_manager import Session, engine, Base
import datetime
import scheduler
from sqlalchemy import and_
import reddit_services
from user import User
from post import Post
from scraped_post import ScrapedPost
# posts id {851944236562776077}
# guild id {851944236562776074}
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
GUILD = os.getenv('DISCORD_GUILD')
DB_PW = os.getenv('DB_PW')
# emojis
ARROW_UP = "\u2B06"
ARROW_DOWN = "\u2B07"
STAR = "\u2B50"
bot = commands.Bot(command_prefix='.')
intents = discord.Intents.default()
intents.members = True
Base.metadata.create_all(engine)
session = Session()
# cron job - send scraped post to channel
async def send_posts_to_channel():
matching_posts_urls = await reddit_services.get_matching_posts_urls('askreddit')
guild = discord.utils.get(bot.guilds, name='Creepy Reddit')
posts = discord.utils.get(guild.text_channels, name='posts')
for url in matching_posts_urls:
print('Sending post to channel: '+url)
msg = await posts.send(url)
await msg.add_reaction(ARROW_UP)
await msg.add_reaction(ARROW_DOWN)
# cron job - post weekly top to channel
async def send_weekly_top():
today = datetime.date.today()
week_ago = today - datetime.timedelta(days=7)
session = ScrapedPost.get_session()
top_posts = session.query(ScrapedPost).filter(and_(
ScrapedPost.created >= week_ago,
ScrapedPost.created <= today)).order_by(ScrapedPost.votes.desc()).limit(3).all()
guild = discord.utils.get(bot.guilds, name='Creepy Reddit')
weekly_top = discord.utils.get(guild.text_channels, name='weekly-top')
text = "Here are the top posts of this week!"
await weekly_top.send(text)
for post in top_posts:
await weekly_top.send(post.url)
@bot.event
async def on_ready():
await reddit_services.start()
await scheduler.start(send_posts_to_channel, send_weekly_top)
bot.run(TOKEN)
reddit_services.py
import os
from dotenv import load_dotenv
import asyncpraw
from scraped_post import ScrapedPost
from datetime import datetime
load_dotenv()
CLIENT_ID = os.getenv('CLIENT_ID')
CLIENT_SECRET = os.getenv('CLIENT_SECRET')
USER_AGENT = os.getenv('USER_AGENT')
USER_NAME = os.getenv('USER_NAME')
PASSWORD = os.getenv('PASSWORD')
# only 1 for testing
keywords = [
"what"
]
reddit = None
async def start():
global reddit
reddit = asyncpraw.Reddit(
client_id = CLIENT_ID,
client_secret = CLIENT_SECRET,
user_agent = USER_AGENT,
username = USER_NAME,
password = PASSWORD
)
user = await reddit.user.me()
if user:
print("Succesfully authenticated to the Reddit API")
async def get_matching_posts_urls(subreddit):
askreddit = await reddit.subreddit(subreddit)
askreddit_hot = askreddit.hot(limit=26)
matching_posts = []
async for submission in askreddit_hot:
lower_title = submission.title.lower()
if any(word in lower_title for word in keywords):
already_scraped = await post_already_scraped(submission.id)
if not already_scraped:
await save_record_of_post(submission)
matching_posts.append(submission.url)
else:
print('Already scraped')
return matching_posts
async def save_record_of_post(submission):
post_id = submission.id
title = submission.title
url = submission.url
created = datetime.fromtimestamp(submission.created)
scraped_post = ScrapedPost(post_id, title, url, created)
try:
scraped_post.save()
return scraped_post
except:
print('Could not save scraped post to DB with id: {post_id}').format(post_id=post_id)
async def post_already_scraped(post_id):
session = ScrapedPost.get_session()
post = session.query(ScrapedPost).filter(ScrapedPost.id == post_id).first()
return post is not None
调度程序.py
from datetime import datetime
from apscheduler.schedulers.asyncio import AsyncIOScheduler
import datetime
async def start(send_posts, send_weekly_top):
scheduler = AsyncIOScheduler()
current_time = datetime.datetime.now()
# scheduler.add_job(send_posts, 'cron', hour='0,3,6,12,21', minute='*', second='*')
scheduler.add_job(send_posts, 'cron', hour='*', minute='*', second='0')
scheduler.add_job(send_weekly_top, 'cron', day='6', hour='18')
try:
print('Starting scheduler...')
scheduler.start()
except Exception as e: print(e)
一旦我在 Heroku 上部署,代码就会到达“正在启动调度程序...”并无限期地停在那里。我昨天把它留了一夜,它达到了超时。
如果我的代码没有明显的问题,我可以得到一些想法来尝试调试它吗?我认为出了点问题,必须有一种方法可以记录某些内容,以便将我发送到正确的方向。
解决方案
推荐阅读
- c# - 在客户端维护数据库
- laravel - laravel 中的“count()”函数有问题。请帮我解决这个问题
- python - 如何指定 forms.select() 必须在 django 中显示的元素
- mongodb - 父子层次结构mongodb聚合管道
- python - 完全停止运行 pyqt5 应用程序
- javascript - js序列化正确格式
- oracle - OSB 12c 的 Jdeveloper 中似乎没有导入的自定义 xpath 函数
- iis - 从 HTTP-Request/Response 对象中检索 IIS 日志参数值
- javascript - Meteor/SSR/Apollo 客户端 - 尝试使用 Apollo 设置 SSR 并没有找到 fetch
- php - 无法在 codeigniter 中按类别过滤数据