fix: addressed several concers raised by thockin
- Renamed [x]HookChannel to [x]hookChannel for consistency
- Made hookChannels buffered chanels of size 1
- Added clarifying documentation and renamed functions expalining how I was
- ensuring that hooks execute at least once, assuming that main thread does not crash
- make sure chanels are not written to more than once
This commit is contained in:
parent
9e6348c3b5
commit
3b5ed549eb
|
|
@ -174,8 +174,10 @@ var (
|
|||
}, []string{"status"})
|
||||
)
|
||||
|
||||
// Channels for ensuring hooks execute at least once before terminating due to GIT_SYNC_ONCE
|
||||
var execHookChannel, webHookChannel chan bool // initialising as null to promptly catch logical errors and to avoid unneeded object creation
|
||||
// Channels for ensuring hooks execute at least once before terminating.
|
||||
// Should be nil if and only if corresponding hook is not defined and if initialised, will only every get written
|
||||
// to once.
|
||||
var exechookChannel, webhookChannel chan bool
|
||||
|
||||
const (
|
||||
metricKeySuccess = "success"
|
||||
|
|
@ -362,8 +364,7 @@ func main() {
|
|||
if *flExechookBackoff < time.Second {
|
||||
handleError(log, true, "ERROR: --exechook-backoff must be at least 1s")
|
||||
}
|
||||
|
||||
execHookChannel = make(chan bool)
|
||||
exechookChannel = make(chan bool, 1)
|
||||
}
|
||||
|
||||
if *flWebhookURL != "" {
|
||||
|
|
@ -376,8 +377,7 @@ func main() {
|
|||
if *flWebhookBackoff < time.Second {
|
||||
handleError(log, true, "ERROR: --webhook-backoff must be at least 1s")
|
||||
}
|
||||
|
||||
webHookChannel = make(chan bool)
|
||||
webhookChannel = make(chan bool, 1)
|
||||
}
|
||||
|
||||
if *flPassword != "" && *flPasswordFile != "" {
|
||||
|
|
@ -563,7 +563,7 @@ func main() {
|
|||
*flWebhookBackoff,
|
||||
hook.NewHookData(),
|
||||
log,
|
||||
webHookChannel,
|
||||
webhookChannel,
|
||||
)
|
||||
go webhookRunner.Run(context.Background())
|
||||
}
|
||||
|
|
@ -584,7 +584,7 @@ func main() {
|
|||
*flExechookBackoff,
|
||||
hook.NewHookData(),
|
||||
log,
|
||||
execHookChannel,
|
||||
exechookChannel,
|
||||
)
|
||||
go exechookRunner.Run(context.Background())
|
||||
}
|
||||
|
|
@ -630,17 +630,17 @@ func main() {
|
|||
}
|
||||
|
||||
if initialSync {
|
||||
// Wait for hooks to complete at least once before checking whether to stop
|
||||
// Wait for hooks to complete at least once, if not nil, before checking whether to stop program
|
||||
// Assumes that if hook channels are not nil, they will have at least one value before getting closed
|
||||
if execHookChannel != nil {
|
||||
execHookChannelFinishedSuccessfully:= <-execHookChannel
|
||||
if !execHookChannelFinishedSuccessfully {
|
||||
if exechookChannel != nil {
|
||||
exechookChannelFinishedSuccessfully := <-exechookChannel
|
||||
if !exechookChannelFinishedSuccessfully {
|
||||
log.Error(nil, "exec hook completed with error")
|
||||
}
|
||||
}
|
||||
if webHookChannel != nil {
|
||||
webHookChannelFinishedSuccessfully:= <-webHookChannel
|
||||
if !webHookChannelFinishedSuccessfully {
|
||||
if webhookChannel != nil {
|
||||
webhookChannelFinishedSuccessfully := <-webhookChannel
|
||||
if !webhookChannelFinishedSuccessfully {
|
||||
log.Error(nil, "web hook completed with error")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,8 @@ type HookRunner struct {
|
|||
data *hookData
|
||||
// Logger
|
||||
logger *logging.Logger
|
||||
// Has succeeded once Chanel, sends true if first run executed successfully and false if it failed
|
||||
// hasCompletedOnce is used to send true if and only if first run executed successfully and false otherwise to some receiver.
|
||||
// should be initialised to a buffered channel of size 1. Is only meant to be used within sendCompletedOnceMessageIfApplicable
|
||||
hasCompletedOnce chan bool
|
||||
}
|
||||
|
||||
|
|
@ -126,21 +127,22 @@ func (r *HookRunner) Run(ctx context.Context) {
|
|||
r.logger.Error(err, "hook failed")
|
||||
updateHookRunCountMetric(r.hook.Name(), "error")
|
||||
// don't want to sleep unnecessarily if we are going to terminate anyways
|
||||
r.sendCompletedOnceMessage(false)
|
||||
r.sendCompletedOnceMessageIfApplicable(false)
|
||||
time.Sleep(r.backoff)
|
||||
} else {
|
||||
updateHookRunCountMetric(r.hook.Name(), "success")
|
||||
lastHash = hash
|
||||
r.sendCompletedOnceMessage(true)
|
||||
r.sendCompletedOnceMessageIfApplicable(true)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sendCompletedOnceMessage forwards the success status (as a boolean) of the first execution of HookRunner, the first time
|
||||
// to the r.hasCompletedOnce channel
|
||||
func (r *HookRunner) sendCompletedOnceMessage(completedSuccessfully bool) {
|
||||
// If hasCompletedOnce is nil, does nothing. Otherwise, forwards the caller provided success status (as a boolean) of
|
||||
// HookRunner to receivers of hasCompletedOnce, closes said chanel, and sets hasCompletedOnce to nil.
|
||||
// Using this function to write to hasCompletedOnce ensures it is only every written to once.
|
||||
func (r *HookRunner) sendCompletedOnceMessageIfApplicable(completedSuccessfully bool) {
|
||||
if r.hasCompletedOnce != nil {
|
||||
r.hasCompletedOnce <- completedSuccessfully
|
||||
close(r.hasCompletedOnce)
|
||||
|
|
|
|||
Loading…
Reference in New Issue