Skip to content

Commit

Permalink
Add 'pollAtLaunch' flag for polling change sources
Browse files Browse the repository at this point in the history
This allows a poller to poll immediately on launch and get
changes that occurred while it was down.
  • Loading branch information
Steve Hoelzer committed Jan 2, 2014
1 parent 8572c1d commit 017c227
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 21 deletions.
8 changes: 6 additions & 2 deletions master/buildbot/changes/base.py
Expand Up @@ -47,12 +47,16 @@ class PollingChangeSource(ChangeSource):
pollInterval = 60
"time (in seconds) between calls to C{poll}"

pollAtLaunch = False
"determines when the first poll occurs. True = immediately on launch, False = wait for one pollInterval."

_loop = None

def __init__(self, name=None, pollInterval=60 * 10):
def __init__(self, name=None, pollInterval=60 * 10, pollAtLaunch=False):
if name:
self.setName(name)
self.pollInterval = pollInterval
self.pollAtLaunch = pollAtLaunch

self.doPoll = util.misc.SerializedInvocation(self.doPoll)

Expand All @@ -76,7 +80,7 @@ def poll(self):

def startLoop(self):
self._loop = task.LoopingCall(self.doPoll)
self._loop.start(self.pollInterval, now=False)
self._loop.start(self.pollInterval, now=self.pollAtLaunch)

def stopLoop(self):
if self._loop and self._loop.running:
Expand Down
6 changes: 3 additions & 3 deletions master/buildbot/changes/bonsaipoller.py
Expand Up @@ -221,12 +221,12 @@ def _getRevision(self):

class BonsaiPoller(base.PollingChangeSource):
compare_attrs = ["bonsaiURL", "pollInterval", "tree",
"module", "branch", "cvsroot"]
"module", "branch", "cvsroot", "pollAtLaunch"]

def __init__(self, bonsaiURL, module, branch, tree="default",
cvsroot="/cvsroot", pollInterval=30, project=''):
cvsroot="/cvsroot", pollInterval=30, project='', pollAtLaunch=False):

base.PollingChangeSource.__init__(self, name=bonsaiURL, pollInterval=pollInterval)
base.PollingChangeSource.__init__(self, name=bonsaiURL, pollInterval=pollInterval, pollAtLaunch=pollAtLaunch)

self.bonsaiURL = bonsaiURL
self.module = module
Expand Down
7 changes: 4 additions & 3 deletions master/buildbot/changes/gitpoller.py
Expand Up @@ -35,21 +35,22 @@ class GitPoller(base.PollingChangeSource, StateMixin):

compare_attrs = ["repourl", "branches", "workdir",
"pollInterval", "gitbin", "usetimestamps",
"category", "project"]
"category", "project", "pollAtLaunch"]

def __init__(self, repourl, branches=None, branch=None,
workdir=None, pollInterval=10 * 60,
gitbin='git', usetimestamps=True,
category=None, project=None,
pollinterval=-2, fetch_refspec=None,
encoding='utf-8'):
encoding='utf-8', pollAtLaunch=False):

# for backward compatibility; the parameter used to be spelled with 'i'
if pollinterval != -2:
pollInterval = pollinterval

base.PollingChangeSource.__init__(self, name=repourl,
pollInterval=pollInterval)
pollInterval=pollInterval,
pollAtLaunch=pollAtLaunch)

if project is None:
project = ''
Expand Down
6 changes: 3 additions & 3 deletions master/buildbot/changes/hgpoller.py
Expand Up @@ -33,15 +33,15 @@ class HgPoller(base.PollingChangeSource):

compare_attrs = ["repourl", "branch", "workdir",
"pollInterval", "hgpoller", "usetimestamps",
"category", "project"]
"category", "project", "pollAtLaunch"]

db_class_name = 'HgPoller'

def __init__(self, repourl, branch='default',
workdir=None, pollInterval=10 * 60,
hgbin='hg', usetimestamps=True,
category=None, project='', pollinterval=-2,
encoding='utf-8'):
encoding='utf-8', pollAtLaunch=False):

# for backward compatibility; the parameter used to be spelled with 'i'
if pollinterval != -2:
Expand All @@ -50,7 +50,7 @@ def __init__(self, repourl, branch='default',
self.repourl = repourl
self.branch = branch
base.PollingChangeSource.__init__(
self, name=repourl, pollInterval=pollInterval)
self, name=repourl, pollInterval=pollInterval, pollAtLaunch=pollAtLaunch)
self.encoding = encoding
self.lastChange = time.time()
self.lastPoll = time.time()
Expand Down
6 changes: 3 additions & 3 deletions master/buildbot/changes/p4poller.py
Expand Up @@ -55,7 +55,7 @@ class P4Source(base.PollingChangeSource, util.ComparableMixin):
them to the change master."""

compare_attrs = ["p4port", "p4user", "p4passwd", "p4base",
"p4bin", "pollInterval"]
"p4bin", "pollInterval", "pollAtLaunch"]

env_vars = ["P4CLIENT", "P4PORT", "P4PASSWD", "P4USER",
"P4CHARSET", "PATH"]
Expand All @@ -76,13 +76,13 @@ def __init__(self, p4port=None, p4user=None, p4passwd=None,
split_file=lambda branchfile: (None, branchfile),
pollInterval=60 * 10, histmax=None, pollinterval=-2,
encoding='utf8', project=None, name=None,
server_tz=None):
server_tz=None, pollAtLaunch=False):

# for backward compatibility; the parameter used to be spelled with 'i'
if pollinterval != -2:
pollInterval = pollinterval

base.PollingChangeSource.__init__(self, name=name, pollInterval=pollInterval)
base.PollingChangeSource.__init__(self, name=name, pollInterval=pollInterval, pollAtLaunch=pollAtLaunch)

if project is None:
project = ''
Expand Down
6 changes: 3 additions & 3 deletions master/buildbot/changes/svnpoller.py
Expand Up @@ -79,7 +79,7 @@ class SVNPoller(base.PollingChangeSource, util.ComparableMixin):
compare_attrs = ["svnurl", "split_file",
"svnuser", "svnpasswd", "project",
"pollInterval", "histmax",
"svnbin", "category", "cachepath"]
"svnbin", "category", "cachepath", "pollAtLaunch"]

parent = None # filled in when we're added
last_change = None
Expand All @@ -90,13 +90,13 @@ def __init__(self, svnurl, split_file=None,
pollInterval=10 * 60, histmax=100,
svnbin='svn', revlinktmpl='', category=None,
project='', cachepath=None, pollinterval=-2,
extra_args=None):
extra_args=None, pollAtLaunch=False):

# for backward compatibility; the parameter used to be spelled with 'i'
if pollinterval != -2:
pollInterval = pollinterval

base.PollingChangeSource.__init__(self, name=svnurl, pollInterval=pollInterval)
base.PollingChangeSource.__init__(self, name=svnurl, pollInterval=pollInterval, pollAtLaunch=pollAtLaunch)

if svnurl.endswith("/"):
svnurl = svnurl[:-1] # strip the trailing slash
Expand Down
20 changes: 20 additions & 0 deletions master/buildbot/test/unit/test_changes_base.py
Expand Up @@ -88,3 +88,23 @@ def check(_):
d.addCallback(check)
reactor.callWhenRunning(d.callback, None)
return d

def test_pollAtLaunch(self):
# track when poll() gets called
loops = []
self.changesource.poll = \
lambda: loops.append(self.clock.seconds())

self.changesource.pollInterval = 5
self.changesource.pollAtLaunch = True
self.startChangeSource()

d = defer.Deferred()
d.addCallback(self.runClockFor, 12)

def check(_):
# note that it *does* poll at time 0
self.assertEqual(loops, [0.0, 5.0, 10.0])
d.addCallback(check)
reactor.callWhenRunning(d.callback, None)
return d
20 changes: 20 additions & 0 deletions master/docs/manual/cfg-changesources.rst
Expand Up @@ -591,6 +591,10 @@ depot for changes. It accepts the following arguments:
``pollInterval``
How often to poll, in seconds. Defaults to 600 (10 minutes).

``pollAtLaunch``
Determines when the first poll occurs. True = immediately on launch,
False = wait for one pollInterval (default).

``histmax``
The maximum number of changes to inspect at a time. If more than this
number occur since the last poll, older changes will be silently
Expand Down Expand Up @@ -658,6 +662,10 @@ changed since the last query.
``pollInterval``
The time (in seconds) between queries for changes.

``pollAtLaunch``
Determines when the first poll occurs. True = immediately on launch,
False = wait for one pollInterval (default).

``project``
The project name to attach to all change objects produced by this
change source.
Expand Down Expand Up @@ -734,6 +742,10 @@ multiple branches.
your svn server. Please be considerate of public SVN repositories by
using a large interval when polling them.

``pollAtLaunch``
Determines when the first poll occurs. True = immediately on launch,
False = wait for one pollInterval (default).

``histmax``
The maximum number of changes to inspect at a time. Every ``pollInterval``
seconds, the :bb:chsrc:`SVNPoller` asks for the last ``histmax`` changes and
Expand Down Expand Up @@ -884,6 +896,10 @@ arguments:
``pollInterval``
interval in seconds between polls, default is 10 minutes

``pollAtLaunch``
Determines when the first poll occurs. True = immediately on launch,
False = wait for one pollInterval (default).

``gitbin``
path to the Git binary, defaults to just ``'git'``

Expand Down Expand Up @@ -972,6 +988,10 @@ The :bb:chsrc:`HgPoller` accepts the following arguments:
``pollInterval``
interval in seconds between polls, default is 10 minutes

``pollAtLaunch``
Determines when the first poll occurs. True = immediately on launch,
False = wait for one pollInterval (default).

``hgbin``
path to the Mercurial binary, defaults to just ``'hg'``

Expand Down
11 changes: 7 additions & 4 deletions master/docs/manual/cfg-statustargets.rst
Expand Up @@ -829,15 +829,18 @@ Poller hook
###########

The poller hook allows you to use GET or POST requests to trigger
polling. One advantage of this is your buildbot instance can (at start
up) poll to get changes that happened while it was down, but then you
can still use a commit hook to get fast notification of new changes.
polling. One advantage of this is your buildbot instance can poll
at launch (using the pollAtLaunch flag) to get changes that happened
while it was down, but then you can still use a commit hook to get
fast notification of new changes.

Suppose you have a poller configured like this::

c['change_source'] = SVNPoller(
svnurl="https://amanda.svn.sourceforge.net/svnroot/amanda/amanda",
split_file=split_file_branches)
split_file=split_file_branches,
pollInterval=24*60*60,
pollAtLaunch=True)

And you configure your WebStatus to enable this hook::

Expand Down
2 changes: 2 additions & 0 deletions master/docs/relnotes/index.rst
Expand Up @@ -131,6 +131,8 @@ Features

* The HGPoller and GitPoller now split filenames on newlines, rather than whitespace, so files containing whitespace are handled correctly.

* Add 'pollAtLaunch' flag for polling change sources. This allows a poller to poll immediately on launch and get changes that occurred while it was down.

Fixes
~~~~~

Expand Down

0 comments on commit 017c227

Please sign in to comment.