lib/fbe/regularly.rb
# frozen_string_literal: true # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy # SPDX-License-Identifier: MIT require_relative '../fbe' require_relative 'fb' # Run the block provided every X days based on PMP configuration. # # Executes a block periodically based on PMP (Project Management Plan) settings. # The block will only run if it hasn't been executed within the specified interval. # Creates a fact recording when the judge was last run. # # @param [String] area The name of the PMP area # @param [String] p_every_days PMP property name for interval (defaults to 7 days if not in PMP) # @param [String] p_since_days PMP property name for since period (defaults to 28 days if not in PMP) # @param [Factbase] fb The factbase (defaults to Fbe.fb) # @param [String] judge The name of the judge (uses $judge global) # @param [Loog] loog The logging facility (uses $loog global) # @yield [Factbase::Fact] Fact to populate with judge execution details # @return [nil] Nothing # @raise [RuntimeError] If required parameters or globals are nil # @note Skips execution if judge was run within the interval period # @note The 'since' property is added to the fact when p_since_days is provided # @example Run a cleanup task every 3 days # Fbe.regularly('cleanup', 'days_between_cleanups', 'cleanup_history_days') do |f| # f.total_cleaned = cleanup_old_records # # PMP might have: days_between_cleanups=3, cleanup_history_days=30 # end def Fbe.regularly(area, p_every_days, p_since_days = nil, fb: Fbe.fb, judge: $judge, loog: $loog, &) raise 'The area is nil' if area.nil? raise 'The p_every_days is nil' if p_every_days.nil? raise 'The fb is nil' if fb.nil? raise 'The $judge is not set' if judge.nil? raise 'The $loog is not set' if loog.nil? pmp = fb.query("(and (eq what 'pmp') (eq area '#{area}') (exists #{p_every_days}))").each.to_a.first interval = pmp.nil? ? 7 : pmp[p_every_days].first unless fb.query( "(and (eq what '#{judge}') (gt when (minus (to_time (env 'TODAY' '#{Time.now.utc.iso8601}')) '#{interval} days')))" ).each.to_a.empty? loog.debug("#{$judge} statistics have recently been collected, skipping now") return end f = fb.insert f.what = judge f.when = Time.now unless p_since_days.nil? days = pmp.nil? ? 28 : pmp[p_since_days].first since = Time.now - (days * 24 * 60 * 60) f.since = since end yield f nil end