def buildGrid(self, request, builders): debug = False # TODO: see if we can use a cached copy showEvents = False if request.args.get("show_events", ["true"])[0].lower() == "true": showEvents = True filterBranches = [b for b in request.args.get("branch", []) if b] filterBranches = map_branches(filterBranches) maxTime = int(request.args.get("last_time", [util.now()])[0]) if "show_time" in request.args: minTime = maxTime - int(request.args["show_time"][0]) elif "first_time" in request.args: minTime = int(request.args["first_time"][0]) else: minTime = None spanLength = 10 # ten-second chunks maxPageLen = int(request.args.get("num_events", [200])[0]) # first step is to walk backwards in time, asking each column # (commit, all builders) if they have any events there. Build up the # array of events, and stop when we have a reasonable number. commit_source = self.getChangemaster(request) lastEventTime = util.now() sources = [commit_source] + builders changeNames = ["changes"] builderNames = map(lambda builder: builder.getName(), builders) sourceNames = changeNames + builderNames sourceEvents = [] sourceGenerators = [] def get_event_from(g): try: while True: e = g.next() # e might be builder.BuildStepStatus, # builder.BuildStatus, builder.Event, # waterfall.Spacer(builder.Event), or changes.Change . # The showEvents=False flag means we should hide # builder.Event . if not showEvents and isinstance(e, builder.Event): continue break event = interfaces.IStatusEvent(e) if debug: log.msg("gen %s gave1 %s" % (g, event.getText())) except StopIteration: event = None return event for s in sources: gen = insertGaps(s.eventGenerator(filterBranches), lastEventTime) sourceGenerators.append(gen) # get the first event sourceEvents.append(get_event_from(gen)) eventGrid = [] timestamps = [] lastEventTime = 0 for e in sourceEvents: if e and e.getTimes()[0] > lastEventTime: lastEventTime = e.getTimes()[0] if lastEventTime == 0: lastEventTime = util.now() spanStart = lastEventTime - spanLength debugGather = 0 while 1: if debugGather: log.msg("checking (%s,]" % spanStart) # the tableau of potential events is in sourceEvents[]. The # window crawls backwards, and we examine one source at a time. # If the source's top-most event is in the window, is it pushed # onto the events[] array and the tableau is refilled. This # continues until the tableau event is not in the window (or is # missing). spanEvents = [] # for all sources, in this span. row of eventGrid firstTimestamp = None # timestamp of first event in the span lastTimestamp = None # last pre-span event, for next span for c in range(len(sourceGenerators)): events = [] # for this source, in this span. cell of eventGrid event = sourceEvents[c] while event and spanStart < event.getTimes()[0]: # to look at windows that don't end with the present, # condition the .append on event.time <= spanFinish if not IBox(event, None): log.msg("BAD EVENT", event, event.getText()) assert 0 if debug: log.msg("pushing", event.getText(), event) events.append(event) starts, finishes = event.getTimes() firstTimestamp = util.earlier(firstTimestamp, starts) event = get_event_from(sourceGenerators[c]) if debug: log.msg("finished span") if event: # this is the last pre-span event for this source lastTimestamp = util.later(lastTimestamp, event.getTimes()[0]) if debugGather: log.msg(" got %s from %s" % (events, sourceNames[c])) sourceEvents[c] = event # refill the tableau spanEvents.append(events) # only show events older than maxTime. This makes it possible to # visit a page that shows what it would be like to scroll off the # bottom of this one. if firstTimestamp is not None and firstTimestamp <= maxTime: eventGrid.append(spanEvents) timestamps.append(firstTimestamp) if lastTimestamp: spanStart = lastTimestamp - spanLength else: # no more events break if minTime is not None and lastTimestamp < minTime: break if len(timestamps) > maxPageLen: break # now loop # loop is finished. now we have eventGrid[] and timestamps[] if debugGather: log.msg("finished loop") assert (len(timestamps) == len(eventGrid)) return (changeNames, builderNames, timestamps, eventGrid, sourceEvents)
def buildGrid(self, request, builders): debug = False # TODO: see if we can use a cached copy showEvents = False if request.args.get("show_events", ["false"])[0].lower() == "true": showEvents = True filterCategories = request.args.get('category', []) filterBranches = [b for b in request.args.get("branch", []) if b] filterBranches = map_branches(filterBranches) maxTime = int(request.args.get("last_time", [util.now()])[0]) if "show_time" in request.args: minTime = maxTime - int(request.args["show_time"][0]) elif "first_time" in request.args: minTime = int(request.args["first_time"][0]) else: minTime = None spanLength = 10 # ten-second chunks maxPageLen = int(request.args.get("num_events", [200])[0]) # first step is to walk backwards in time, asking each column # (commit, all builders) if they have any events there. Build up the # array of events, and stop when we have a reasonable number. commit_source = self.getChangemaster(request) lastEventTime = util.now() sources = [commit_source] + builders changeNames = ["changes"] builderNames = map(lambda builder: builder.getName(), builders) sourceNames = changeNames + builderNames sourceEvents = [] sourceGenerators = [] def get_event_from(g): try: while True: e = g.next() # e might be builder.BuildStepStatus, # builder.BuildStatus, builder.Event, # waterfall.Spacer(builder.Event), or changes.Change . # The showEvents=False flag means we should hide # builder.Event . if not showEvents and isinstance(e, builder.Event): continue break event = interfaces.IStatusEvent(e) if debug: log.msg("gen %s gave1 %s" % (g, event.getText())) except StopIteration: event = None return event for s in sources: gen = insertGaps(s.eventGenerator(filterBranches, filterCategories), showEvents, lastEventTime) sourceGenerators.append(gen) # get the first event sourceEvents.append(get_event_from(gen)) eventGrid = [] timestamps = [] lastEventTime = 0 for e in sourceEvents: if e and e.getTimes()[0] > lastEventTime: lastEventTime = e.getTimes()[0] if lastEventTime == 0: lastEventTime = util.now() spanStart = lastEventTime - spanLength debugGather = 0 while 1: if debugGather: log.msg("checking (%s,]" % spanStart) # the tableau of potential events is in sourceEvents[]. The # window crawls backwards, and we examine one source at a time. # If the source's top-most event is in the window, is it pushed # onto the events[] array and the tableau is refilled. This # continues until the tableau event is not in the window (or is # missing). spanEvents = [] # for all sources, in this span. row of eventGrid firstTimestamp = None # timestamp of first event in the span lastTimestamp = None # last pre-span event, for next span for c in range(len(sourceGenerators)): events = [] # for this source, in this span. cell of eventGrid event = sourceEvents[c] while event and spanStart < event.getTimes()[0]: # to look at windows that don't end with the present, # condition the .append on event.time <= spanFinish if not IBox(event, None): log.msg("BAD EVENT", event, event.getText()) assert 0 if debug: log.msg("pushing", event.getText(), event) events.append(event) starts, finishes = event.getTimes() firstTimestamp = util.earlier(firstTimestamp, starts) event = get_event_from(sourceGenerators[c]) if debug: log.msg("finished span") if event: # this is the last pre-span event for this source lastTimestamp = util.later(lastTimestamp, event.getTimes()[0]) if debugGather: log.msg(" got %s from %s" % (events, sourceNames[c])) sourceEvents[c] = event # refill the tableau spanEvents.append(events) # only show events older than maxTime. This makes it possible to # visit a page that shows what it would be like to scroll off the # bottom of this one. if firstTimestamp is not None and firstTimestamp <= maxTime: eventGrid.append(spanEvents) timestamps.append(firstTimestamp) if lastTimestamp: spanStart = lastTimestamp - spanLength else: # no more events break if minTime is not None and lastTimestamp < minTime: break if len(timestamps) > maxPageLen: break # now loop # loop is finished. now we have eventGrid[] and timestamps[] if debugGather: log.msg("finished loop") assert(len(timestamps) == len(eventGrid)) return (changeNames, builderNames, timestamps, eventGrid, sourceEvents)