An example of a function that I mentioned in comment:
create table update_status(id
insert into update_status values (1, now()); integer, last_update timestamp);
CREATE OR REPLACE FUNCTION public.update_check()
RETURNS void
LANGUAGE plpgsql
AS $function$
DECLARE
_last_update timestamp;
_update_togo interval;
_update_interval interval := '20 secs ';
_sleep_interval interval;
_select_val varchar;
BEGIN
select into _last_update last_update from update_status where id = 1;
select into _update_togo now() - _last_update;
if _update_togo < _update_interval then
RAISE NOTICE 'Now start %', clock_timestamp();
RAISE NOTICE 'Interval %', _update_togo;
select into _sleep_interval _update_interval - _update_togo;
RAISE NOTICE 'Sleep interval %', _sleep_interval;
perform pg_sleep_for(_sleep_interval);
select into _select_val 'Run at';
RAISE NOTICE '% %', _select_val,clock_timestamp();
end if;
END;
$function$
;
update update_status set last_update = now();
select update_check();
NOTICE: Now start 2023-01-16 11:53:15.936465-08
NOTICE: Interval 00:00:07.314329
NOTICE: Sleep interval 00:00:12.685671
NOTICE: Run at 2023-01-16 11:53:28.634306-08
update_check
--------------
This is a simplistic proof of concept and would need more work to deal with exceptions.