nonebot / plugin-apscheduler

APScheduler Support for NoneBot2
https://nonebot.dev/docs/best-practice/scheduler
MIT License
85 stars 10 forks source link

修改任务时间问题 #12

Closed InariInDream closed 2 years ago

InariInDream commented 2 years ago

想在插件中实现定时查询一个api里的时间,再使用查询到的最新时间进行定时提醒。 查了一下APScheduler的文档,想用scheduler.reschedule_job来实现 这样的话需要在最开始add_job时候加上一个参数id,但这样会报错,查了一下好像是add_job()里面func参数的缺失,似乎是没检测到后面的async def(?

image

我的大致代码如下

from nonebot_plugin_apscheduler import scheduler

time_notice2 = require("nonebot_plugin_apscheduler").scheduler
time_update1 = require("nonebot_plugin_apscheduler").scheduler

with open(filename) as f_obj:
     j = json.load(f_obj)
     cf_date = j['cf_time']

# 提前2小时提醒
@time_notice2.add_job("date", run_date=cf_date, id="notice2")  # 报错在这行
async def notice_cf2():
    ......
    logger.info(f"已发送提前2h提醒")

# 每隔5秒更新一次时间
@time_update1.scheduled_job('interval', seconds=5)
async def update_time():
     ......
     if ok == 1:
         with open(filename) as f_obj:
             j = json.load()
         scheduler.reschedule_job(job_id='notice2', trigger='date', run_date=j['cf_time'])

还是说有其他实现方法呢,求指导一下qwq

yanyongyu commented 2 years ago

你的apscheduler版本是?在apscheduler源码中无法定位到你的报错,是不是版本太老了(

InariInDream commented 2 years ago

你的apscheduler版本是?在apscheduler源码中无法定位到你的报错,是不是版本太老了( image image

apscheduler是3.9.1,nonebot-plugin-apscheduler是0.1.3 我这里找到的源码是这样的

def ref_to_obj(ref):
    """
    Returns the object pointed to by ``ref``.

    :type ref: str

    """
    if not isinstance(ref, six.string_types):
        raise TypeError('References must be strings')
    if ':' not in ref:
        raise ValueError('Invalid reference')

    modulename, rest = ref.split(':', 1)
    try:
        obj = __import__(modulename, fromlist=[rest])
    except ImportError:
        raise LookupError('Error resolving reference %s: could not import module' % ref)

    try:
        for name in rest.split('.'):
            obj = getattr(obj, name)
        return obj
    except Exception:
        raise LookupError('Error resolving reference %s: error looking up object' % ref)
yanyongyu commented 2 years ago

看了下,你用错了方法。。。。是scheduled_job不是add_job

另外scheduler不需要require两个

scheduler = require("nonebot_plugin_apscheduler").scheduler

@scheduler.scheduled_job("cron", hour="*/2", id="xxx", args=[1], kwargs={arg2: 2})
async def run_every_2_hour(arg1, arg2):
    pass
InariInDream commented 2 years ago

我最开始用add_job的原因是因为在官方的文档看到了这段话

There are two ways to add jobs to a scheduler:

  1. by calling add_job()

  2. by decorating a function with scheduled_job()

The first way is the most common way to do it. The second way is mostly a convenience to declare jobs that don’t change during the application’s run time. The add_job() method returns a apscheduler.job.Job instance that you can use to modify or remove the job later.

主要是那句 The second way is mostly a convenience to declare jobs that don’t change during the application’s run time. 所以我才用的add_job

改用scheduled_job之后,我写了段测试代码。发现还是有点小问题, 就是似乎在事件触发之前修改时间是可行的,但是在事件触发之后或者在事件触发时修改时间都会提示'No job by the id of test1 was found'的错误,可能是触发之后id就不能够用了(?

如果这样的话,似乎只有用interval每隔一段时间抓取一次api上的时间,然后判断当前时间是否符合要求再进行响应了qwq

感谢您的帮助

yanyongyu commented 2 years ago

date类型的job只会执行一次

InariInDream commented 2 years ago

原来如此