time.sleep() 在 plpythonu 中有 60 秒的限制?

time.sleep() has 60 sec limit in plpythonu?

注意:我是 运行 Postgres 11.7 和 Python 2.7.17。

看来 time.sleep() 在 plpythonu 函数中有 60 秒的限制。它按预期工作长达 60 秒。但如果传递的值大于 60,则它会在 60 秒时停止。

CREATE OR REPLACE FUNCTION test_sleep(interval_str INTERVAL)
    RETURNS INTERVAL
AS $$
    try:
        import time
        import datetime

        start_time = time.time()
        t = datetime.datetime.strptime(interval_str,"%H:%M:%S")
        tdelta = datetime.timedelta(hours=t.hour, minutes=t.minute, seconds=t.second)
        interval_secs = tdelta.total_seconds()
        print 'interval_secs=%s' % repr(interval_secs)
        time.sleep(interval_secs)
        elapsed_secs = time.time() - start_time
        return datetime.timedelta(seconds=elapsed_secs)
    except:
        import traceback
        print traceback.format_exc()
        raise
$$ LANGUAGE PLPYTHONU;

这是使用 psql 在命令行上进行的测试。第一个测试按预期运行。我告诉它睡两秒钟,它就消失了。第二个测试只睡了 60 秒,尽管我要求睡 120 秒。

$ echo "select now(), test_sleep('2 sec'); select now();" | psql
             now              |   test_sleep
------------------------------+-----------------
 2021-05-07 11:10:27.63041-04 | 00:00:02.005745
(1 row)

              now
-------------------------------
 2021-05-07 11:10:29.652542-04
(1 row)

$ echo "select now(), test_sleep('2 min'); select now();" | psql
              now              |   test_sleep
-------------------------------+-----------------
 2021-05-07 11:10:36.056578-04 | 00:00:59.977787
(1 row)

              now
-------------------------------
 2021-05-07 11:11:36.050637-04
(1 row)

$ 

这是 Postgres 日志文件的输出。

interval_secs=2.0
interval_secs=120.0

这并不出乎意料(尽管我无法可靠地重现它)。

https://realpython.com/python-sleep/

Note: In Python 3.5, the core developers changed the behavior of time.sleep() slightly. The new Python sleep() system call will last at least the number of seconds you’ve specified, even if the sleep is interrupted by a signal. This does not apply if the signal itself raises an exception, however.

所以在 python2 中,如果被信号打断,time.sleep 可以提前 return。如果您不喜欢这样,请让它在剩余时间再次循环休眠。