github.com/abayer/test-infra@v0.0.5/mungegithub/mungers/matchers/comment/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 comment
    18  
    19  import (
    20  	"time"
    21  )
    22  
    23  // Pinger checks if it's time to send a ping.
    24  // You can build a pinger for a specific use-case and re-use it when you want.
    25  type Pinger struct {
    26  	botName string
    27  
    28  	keyword     string        // Short description for the ping
    29  	description string        // Long description for the ping
    30  	timePeriod  time.Duration // How often should we ping
    31  	maxCount    int           // Will stop pinging after that many occurrences
    32  }
    33  
    34  // NewPinger creates a new pinger. `keyword` is the name of the notification.
    35  func NewPinger(keyword, botName string) *Pinger {
    36  	return &Pinger{
    37  		botName: botName,
    38  		keyword: keyword,
    39  	}
    40  }
    41  
    42  // SetDescription is the description that goes along the ping
    43  func (p *Pinger) SetDescription(description string) *Pinger {
    44  	p.description = description
    45  
    46  	return p
    47  }
    48  
    49  // SetTimePeriod is the time we wait between pings
    50  func (p *Pinger) SetTimePeriod(timePeriod time.Duration) *Pinger {
    51  	p.timePeriod = timePeriod
    52  
    53  	return p
    54  }
    55  
    56  // SetMaxCount will make the pinger fail when it reaches maximum
    57  func (p *Pinger) SetMaxCount(maxCount int) *Pinger {
    58  	p.maxCount = maxCount
    59  
    60  	return p
    61  }
    62  
    63  // PingNotification creates a new notification to ping `who`
    64  func (p *Pinger) PingNotification(comments []*Comment, who string, startDate *time.Time) *Notification {
    65  	if startDate == nil {
    66  		startDate = &time.Time{}
    67  	}
    68  
    69  	pings := FilterComments(
    70  		comments,
    71  		And([]Matcher{
    72  			CreatedAfter(*startDate),
    73  			MungerNotificationName(p.keyword, p.botName),
    74  		}),
    75  	)
    76  
    77  	// We have pinged too many times, it's time to try something else
    78  	if p.isMaxReached(pings) {
    79  		return nil
    80  	}
    81  
    82  	if !p.shouldPingNow(pings, startDate) {
    83  		return nil
    84  	}
    85  
    86  	return &Notification{
    87  		Name:      p.keyword,
    88  		Arguments: who,
    89  		Context:   p.description,
    90  	}
    91  }
    92  
    93  // IsMaxReached tells you if you've reached the limit yet
    94  func (p *Pinger) IsMaxReached(comments []*Comment, startDate *time.Time) bool {
    95  	if startDate == nil {
    96  		startDate = &time.Time{}
    97  	}
    98  	return p.isMaxReached(FilterComments(
    99  		comments,
   100  		And([]Matcher{
   101  			CreatedAfter(*startDate),
   102  			MungerNotificationName(p.keyword, p.botName),
   103  		}),
   104  	))
   105  }
   106  
   107  func (p *Pinger) isMaxReached(pings FilteredComments) bool {
   108  	return p.maxCount != 0 && len(pings) >= p.maxCount
   109  }
   110  
   111  func (p *Pinger) shouldPingNow(pings FilteredComments, startDate *time.Time) bool {
   112  	lastEvent := startDate
   113  
   114  	if len(pings) != 0 {
   115  		lastEvent = pings[len(pings)-1].CreatedAt
   116  	}
   117  
   118  	return time.Since(*lastEvent) > p.timePeriod
   119  }