Module RSCM::RevisionPoller
In: lib/rscm/revision_poller.rb

Methods

poll  

Constants

CRITICAL_REVISION_SIZE = 100   This is the number of revisions we’ll try to stick to for each call to revisions.
BASE_INCREMENT = 60*60
TWENTY_FOUR_HOURS = 24*60*60

Attributes

logger  [RW] 

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.

[Source]

    # File lib/rscm/revision_poller.rb, line 29
29:     def poll(point=nil, direction=:backwards, multiplier=1, now=Time.now.utc, options={}, &proc)
30:       raise "A block of arity 1 must be called" if proc.nil?
31:       backwards = direction == :backwards      
32:       point ||= now
33:       
34:       if point.respond_to?(:time)
35:         point_time = backwards ? point.time(:min) : point.time(:max)
36:         point_identifier = backwards ? point.identifier(:min) : point.identifier(:max)
37:       elsif point.is_a?(Time)
38:         point_time = point
39:         point_identifier = point
40:       else
41:         point_time = now
42:         point_identifier = point
43:       end
44: 
45:       increment = multiplier * BASE_INCREMENT
46:       if backwards
47:         to = point_identifier
48:         begin
49:           from = point_time - increment
50:         rescue ArgumentError
51:           from = Time.epoch
52:         end
53:         from = Time.epoch if from < Time.epoch
54:       else
55:         from = point_identifier
56:         begin
57:           to = point_time + increment
58:         rescue RangeError
59:           raise "RSCM will not work this far in the future (#{from} plus #{increment})"
60:         end
61:       end
62: 
63:       options = options.merge({:to_identifier => to})
64: 
65:       revs = revisions(from, options)
66:       raise "Got nil revision for from=#{from.inspect}" if revs.nil?
67:       revs.sort!
68:       proc.call(revs)
69: 
70:       if from == Time.epoch
71:         return
72:       end
73:       if !backwards and to.is_a?(Time) and (to) > now + TWENTY_FOUR_HOURS
74:         return
75:       end
76: 
77:       if(revs.length < CRITICAL_REVISION_SIZE)
78:         # We can do more

79:         multiplier *= 2
80:       end
81:       if(revs.length > 2*CRITICAL_REVISION_SIZE)
82:         # We must do less

83:         multiplier /= 2
84:       end
85: 
86:       unless(revs.empty?)
87:         point = backwards ? revs[0] : revs[-1]
88:       end
89:       poll(point, direction, multiplier, now, options, &proc)
90:     end

[Validate]