问题描述
注意:我正在运行 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 的命令行测试。第一个测试按预期运行。我告诉它睡两秒钟,然后它就消失了。即使我请求睡眠 120 秒,第二个测试也只睡眠了 60 秒。
$ 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/
注意:在 Python 3.5 中,核心开发人员改变了 time.sleep() 稍微。新的 Python sleep() 系统调用将持续到 至少你指定的秒数,即使睡眠是 被信号中断。这不适用于信号本身 但是,会引发异常。
所以在python2中,如果被信号中断,time.sleep可以提前返回。如果你不喜欢那样,让它在剩下的时间里循环睡眠。