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"})
|
}, []string{"status"})
|
||||||
)
|
)
|
||||||
|
|
||||||
// Channels for ensuring hooks execute at least once before terminating due to GIT_SYNC_ONCE
|
// Channels for ensuring hooks execute at least once before terminating.
|
||||||
var execHookChannel, webHookChannel chan bool // initialising as null to promptly catch logical errors and to avoid unneeded object creation
|
// 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 (
|
const (
|
||||||
metricKeySuccess = "success"
|
metricKeySuccess = "success"
|
||||||
|
|
@ -362,8 +364,7 @@ func main() {
|
||||||
if *flExechookBackoff < time.Second {
|
if *flExechookBackoff < time.Second {
|
||||||
handleError(log, true, "ERROR: --exechook-backoff must be at least 1s")
|
handleError(log, true, "ERROR: --exechook-backoff must be at least 1s")
|
||||||
}
|
}
|
||||||
|
exechookChannel = make(chan bool, 1)
|
||||||
execHookChannel = make(chan bool)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if *flWebhookURL != "" {
|
if *flWebhookURL != "" {
|
||||||
|
|
@ -376,8 +377,7 @@ func main() {
|
||||||
if *flWebhookBackoff < time.Second {
|
if *flWebhookBackoff < time.Second {
|
||||||
handleError(log, true, "ERROR: --webhook-backoff must be at least 1s")
|
handleError(log, true, "ERROR: --webhook-backoff must be at least 1s")
|
||||||
}
|
}
|
||||||
|
webhookChannel = make(chan bool, 1)
|
||||||
webHookChannel = make(chan bool)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if *flPassword != "" && *flPasswordFile != "" {
|
if *flPassword != "" && *flPasswordFile != "" {
|
||||||
|
|
@ -563,7 +563,7 @@ func main() {
|
||||||
*flWebhookBackoff,
|
*flWebhookBackoff,
|
||||||
hook.NewHookData(),
|
hook.NewHookData(),
|
||||||
log,
|
log,
|
||||||
webHookChannel,
|
webhookChannel,
|
||||||
)
|
)
|
||||||
go webhookRunner.Run(context.Background())
|
go webhookRunner.Run(context.Background())
|
||||||
}
|
}
|
||||||
|
|
@ -584,7 +584,7 @@ func main() {
|
||||||
*flExechookBackoff,
|
*flExechookBackoff,
|
||||||
hook.NewHookData(),
|
hook.NewHookData(),
|
||||||
log,
|
log,
|
||||||
execHookChannel,
|
exechookChannel,
|
||||||
)
|
)
|
||||||
go exechookRunner.Run(context.Background())
|
go exechookRunner.Run(context.Background())
|
||||||
}
|
}
|
||||||
|
|
@ -630,17 +630,17 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if initialSync {
|
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
|
// Assumes that if hook channels are not nil, they will have at least one value before getting closed
|
||||||
if execHookChannel != nil {
|
if exechookChannel != nil {
|
||||||
execHookChannelFinishedSuccessfully:= <-execHookChannel
|
exechookChannelFinishedSuccessfully := <-exechookChannel
|
||||||
if !execHookChannelFinishedSuccessfully {
|
if !exechookChannelFinishedSuccessfully {
|
||||||
log.Error(nil, "exec hook completed with error")
|
log.Error(nil, "exec hook completed with error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if webHookChannel != nil {
|
if webhookChannel != nil {
|
||||||
webHookChannelFinishedSuccessfully:= <-webHookChannel
|
webhookChannelFinishedSuccessfully := <-webhookChannel
|
||||||
if !webHookChannelFinishedSuccessfully {
|
if !webhookChannelFinishedSuccessfully {
|
||||||
log.Error(nil, "web hook completed with error")
|
log.Error(nil, "web hook completed with error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,8 @@ type HookRunner struct {
|
||||||
data *hookData
|
data *hookData
|
||||||
// Logger
|
// Logger
|
||||||
logger *logging.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
|
hasCompletedOnce chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,21 +127,22 @@ func (r *HookRunner) Run(ctx context.Context) {
|
||||||
r.logger.Error(err, "hook failed")
|
r.logger.Error(err, "hook failed")
|
||||||
updateHookRunCountMetric(r.hook.Name(), "error")
|
updateHookRunCountMetric(r.hook.Name(), "error")
|
||||||
// don't want to sleep unnecessarily if we are going to terminate anyways
|
// don't want to sleep unnecessarily if we are going to terminate anyways
|
||||||
r.sendCompletedOnceMessage(false)
|
r.sendCompletedOnceMessageIfApplicable(false)
|
||||||
time.Sleep(r.backoff)
|
time.Sleep(r.backoff)
|
||||||
} else {
|
} else {
|
||||||
updateHookRunCountMetric(r.hook.Name(), "success")
|
updateHookRunCountMetric(r.hook.Name(), "success")
|
||||||
lastHash = hash
|
lastHash = hash
|
||||||
r.sendCompletedOnceMessage(true)
|
r.sendCompletedOnceMessageIfApplicable(true)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendCompletedOnceMessage forwards the success status (as a boolean) of the first execution of HookRunner, the first time
|
// If hasCompletedOnce is nil, does nothing. Otherwise, forwards the caller provided success status (as a boolean) of
|
||||||
// to the r.hasCompletedOnce channel
|
// HookRunner to receivers of hasCompletedOnce, closes said chanel, and sets hasCompletedOnce to nil.
|
||||||
func (r *HookRunner) sendCompletedOnceMessage(completedSuccessfully bool) {
|
// 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 {
|
if r.hasCompletedOnce != nil {
|
||||||
r.hasCompletedOnce <- completedSuccessfully
|
r.hasCompletedOnce <- completedSuccessfully
|
||||||
close(r.hasCompletedOnce)
|
close(r.hasCompletedOnce)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue