class Fbe::Iterate

License
MIT
Copyright
Copyright © 2024-2025 Zerocracy
Author

Yegor Bugayenko (yegor256@gmail.com)
beginning.
function keeps repeating the cycle. Otherwise, it will restart from the
query returns an integer that is different from the previously seen, the
in the +$options+, trying to run the provided query for each of them. If the
Here, you go through all repositories defined by the repositories option
An iterator.

def as(label)

Returns:
  • (nil) - Nothing

Parameters:
  • label (String) -- The label
def as(label)
  raise 'Label is already set' unless @label.nil?
  raise 'Cannot set "label" to nil' if label.nil?
  @label = label
end

def by(query)

Returns:
  • (nil) - Nothing

Parameters:
  • query (String) -- The query
def by(query)
  raise 'Query is already set' unless @query.nil?
  raise 'Cannot set query to nil' if query.nil?
  @query = query
end

def initialize(fb:, loog:, options:, global:)

Parameters:
  • global (Hash) -- The hash for global caching
  • options (Judges::Options) -- The options coming from the +judges+ tool
  • loog (Loog) -- The logging facility
  • fb (Factbase) -- The factbase
def initialize(fb:, loog:, options:, global:)
  @fb = fb
  @loog = loog
  @options = options
  @global = global
  @label = nil
  @since = 0
  @query = nil
  @repeats = 1
  @quota_aware = false
end

def over(timeout: 2 * 60, &)

Returns:
  • (nil) - Nothing

Other tags:
    Yield: - Repository ID and the next number to be considered

Parameters:
  • timeout (Float) -- How many seconds to spend as a maximum
def over(timeout: 2 * 60, &)
  raise 'Use "as" first' if @label.nil?
  raise 'Use "by" first' if @query.nil?
  seen = {}
  oct = Fbe.octo(loog: @loog, options: @options, global: @global)
  repos = Fbe.unmask_repos(loog: @loog, options: @options, global: @global)
  restarted = []
  start = Time.now
  loop do
    repos.each do |repo|
      if Time.now - start > timeout
        $loog.info("We are doing this for #{start.ago} already, won't check #{repo}")
        next
      end
      next if restarted.include?(repo)
      seen[repo] = 0 if seen[repo].nil?
      if seen[repo] >= @repeats
        @loog.debug("We've seen too many (#{seen[repo]}) in #{repo}, let's see next one")
        next
      end
      rid = oct.repo_id_by_name(repo)
      before = @fb.query(
        "(agg (and (eq what '#{@label}') (eq where 'github') (eq repository #{rid})) (first latest))"
      ).one
      @fb.query("(and (eq what '#{@label}') (eq where 'github') (eq repository #{rid}))").delete!
      before = before.nil? ? @since : before.first
      nxt = @fb.query(@query).one(@fb, before:, repository: rid)
      after =
        if nxt.nil?
          @loog.debug("Next element after ##{before} not suggested, re-starting from ##{@since}: #{@query}")
          restarted << repo
          @since
        else
          @loog.debug("Next is ##{nxt}, starting from it...")
          yield(rid, nxt)
        end
      raise "Iterator must return an Integer, while #{after.class} returned" unless after.is_a?(Integer)
      f = @fb.insert
      f.where = 'github'
      f.repository = rid
      f.latest =
        if after.nil?
          @loog.debug("After is nil at #{repo}, setting the 'latest' to ##{nxt}")
          nxt
        else
          @loog.debug("After is ##{after} at #{repo}, setting the 'latest' to it")
          after
        end
      f.what = @label
      seen[repo] += 1
      if oct.off_quota
        @loog.debug('We are off GitHub quota, time to stop')
        break
      end
    end
    if oct.off_quota
      @loog.info("We are off GitHub quota, time to stop after #{start.ago}")
      break
    end
    unless seen.any? { |r, v| v < @repeats && !restarted.include?(r) }
      @loog.debug("No more repos to scan (out of #{repos.size}), quitting after #{start.ago}")
      break
    end
    if restarted.size == repos.size
      @loog.debug("All #{repos.size} repos restarted, quitting after #{start.ago}")
      break
    end
    if Time.now - start > timeout
      $loog.info("We are iterating for #{start.ago} already, time to give up")
      break
    end
  end
  @loog.debug("Finished scanning #{repos.size} repos in #{start.ago}: #{seen.map { |k, v| "#{k}:#{v}" }.join(', ')}")
end

def quota_aware

Returns:
  • (nil) - Nothing
def quota_aware
  @quota_aware = true
end

def repeats(repeats)

Returns:
  • (nil) - Nothing

Parameters:
  • repeats (Integer) -- The total count of them
def repeats(repeats)
  raise 'Cannot set "repeats" to nil' if repeats.nil?
  raise 'The "repeats" must be a positive integer' unless repeats.positive?
  @repeats = repeats
end