github.com/abayer/test-infra@v0.0.5/mungegithub/mungers/matchers/pinger.go (about)

     1  /*
     2  Copyright 2016 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package matchers
    18  
    19  import (
    20  	"time"
    21  
    22  	"github.com/google/go-github/github"
    23  )
    24  
    25  // Pinger checks if it's time to send a ping.
    26  // You can build a pinger for a specific use-case and re-use it when you want.
    27  type Pinger struct {
    28  	botName string
    29  
    30  	keyword     string        // Short description for the ping
    31  	description string        // Long description for the ping
    32  	timePeriod  time.Duration // How often should we ping
    33  	maxCount    int           // Will stop pinging after that many occurrences
    34  }
    35  
    36  // NewPinger creates a new pinger. `keyword` is the name of the notification.
    37  func NewPinger(keyword, botName string) *Pinger {
    38  	return &Pinger{
    39  		botName: botName,
    40  		keyword: keyword,
    41  	}
    42  }
    43  
    44  // SetDescription is the description that goes along the ping
    45  func (p *Pinger) SetDescription(description string) *Pinger {
    46  	p.description = description
    47  
    48  	return p
    49  }
    50  
    51  // SetTimePeriod is the time we wait between pings
    52  func (p *Pinger) SetTimePeriod(timePeriod time.Duration) *Pinger {
    53  	p.timePeriod = timePeriod
    54  
    55  	return p
    56  }
    57  
    58  // SetMaxCount will make the pinger fail when it reaches maximum
    59  func (p *Pinger) SetMaxCount(maxCount int) *Pinger {
    60  	p.maxCount = maxCount
    61  
    62  	return p
    63  }
    64  
    65  // PingNotification creates a new notification to ping `who`
    66  func (p *Pinger) PingNotification(comments []*github.IssueComment, who string, startDate *time.Time) *Notification {
    67  	if startDate == nil {
    68  		startDate = &time.Time{}
    69  	}
    70  
    71  	pings := p.getPings(comments, startDate)
    72  
    73  	// We have pinged too many times, it's time to try something else
    74  	if p.isMaxReached(pings) {
    75  		return nil
    76  	}
    77  
    78  	if !p.shouldPingNow(pings, startDate) {
    79  		return nil
    80  	}
    81  
    82  	return &Notification{
    83  		Name:      p.keyword,
    84  		Arguments: who,
    85  		Context:   p.description,
    86  	}
    87  }
    88  
    89  // IsMaxReached tells you if you've reached the limit yet
    90  func (p *Pinger) IsMaxReached(comments []*github.IssueComment, startDate *time.Time) bool {
    91  	if startDate == nil {
    92  		startDate = &time.Time{}
    93  	}
    94  	return p.isMaxReached(p.getPings(comments, startDate))
    95  }
    96  
    97  func (p *Pinger) getPings(comments []*github.IssueComment, startDate *time.Time) Items {
    98  	return Items{}.
    99  		AddComments(comments...).
   100  		Filter(MungerNotificationName(p.keyword, p.botName)).
   101  		Filter(UpdatedAfter(*startDate))
   102  }
   103  
   104  func (p *Pinger) isMaxReached(pings Items) bool {
   105  	return p.maxCount != 0 && len(pings) >= p.maxCount
   106  }
   107  
   108  func (p *Pinger) shouldPingNow(pings Items, startDate *time.Time) bool {
   109  	lastEvent := startDate
   110  
   111  	if len(pings) != 0 {
   112  		lastEvent = pings[len(pings)-1].Date()
   113  	}
   114  
   115  	return time.Since(*lastEvent) > p.timePeriod
   116  }