module RSCM::RevisionPoller
Constants
- BASE_INCREMENT
- CRITICAL_REVISION_SIZE
This is the number of revisions we'll try to stick to for each call to revisions.
- TWENTY_FOUR_HOURS
Attributes
Public Instance Methods
Polls revisions from point
and either backwards in time until
the beginning of time (Time.epoch) or forward in time until we're past
now
.
Whether to poll forwards or backwards in time depends on the value of
direction
.
The point
argument can be either a Revision, String, Time
or Fixnum representing where to start from (upper boundary for backwards
polling, lower boundary for forwards polling).
The polling starts with a small interval from point
(1 hour)
and increments (or decrements) gradually in order to try and keep the
length of the yielded Revisions to about 100.
The passed block will be called several times, each time with a Revisions object. In order to reduce the memory footprint and keep the performance decent, the length of each yielded Revisions object will usually be within the order of magnitude of 100.
TODO: handle non-transactional SCMs. There was some handling of this in older revisions of this file. We should dig it out and reenable it.
# File lib/rscm/revision_poller.rb, line 29 def poll(point=nil, direction=:backwards, multiplier=1, now=Time.now.utc, options={}, &proc) raise "A block of arity 1 must be called" if proc.nil? backwards = direction == :backwards point ||= now if point.respond_to?(:time) point_time = backwards ? point.time(:min) : point.time(:max) point_identifier = backwards ? point.identifier(:min) : point.identifier(:max) elsif point.is_a?(Time) point_time = point point_identifier = point else point_time = now point_identifier = point end increment = multiplier * BASE_INCREMENT if backwards to = point_identifier begin from = point_time - increment rescue ArgumentError from = Time.epoch end from = Time.epoch if from < Time.epoch else from = point_identifier begin to = point_time + increment rescue RangeError raise "RSCM will not work this far in the future (#{from} plus #{increment})" end end options = options.merge({:to_identifier => to}) revs = revisions(from, options) raise "Got nil revision for from=#{from.inspect}" if revs.nil? revs.sort! proc.call(revs) if from == Time.epoch return end if !backwards and to.is_a?(Time) and (to) > now + TWENTY_FOUR_HOURS return end if(revs.length < CRITICAL_REVISION_SIZE) # We can do more multiplier *= 2 end if(revs.length > 2*CRITICAL_REVISION_SIZE) # We must do less multiplier /= 2 end unless(revs.empty?) point = backwards ? revs[0] : revs[-1] end poll(point, direction, multiplier, now, options, &proc) end