fix: resolve issue number 463
Resolved original issue by introducing a boolean chanel by which exechook runner can communicate with main thread. Then introduced and used webhook executed-at-least-once chanel and added documentation explaining sections of of code only executed when git-sync pulls for first time.
This commit is contained in:
parent
eb822be2e5
commit
9e6348c3b5
|
|
@ -174,6 +174,9 @@ var (
|
||||||
}, []string{"status"})
|
}, []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
|
||||||
|
|
||||||
const (
|
const (
|
||||||
metricKeySuccess = "success"
|
metricKeySuccess = "success"
|
||||||
metricKeyError = "error"
|
metricKeyError = "error"
|
||||||
|
|
@ -359,6 +362,8 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *flWebhookURL != "" {
|
if *flWebhookURL != "" {
|
||||||
|
|
@ -371,6 +376,8 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *flPassword != "" && *flPasswordFile != "" {
|
if *flPassword != "" && *flPasswordFile != "" {
|
||||||
|
|
@ -556,6 +563,7 @@ func main() {
|
||||||
*flWebhookBackoff,
|
*flWebhookBackoff,
|
||||||
hook.NewHookData(),
|
hook.NewHookData(),
|
||||||
log,
|
log,
|
||||||
|
webHookChannel,
|
||||||
)
|
)
|
||||||
go webhookRunner.Run(context.Background())
|
go webhookRunner.Run(context.Background())
|
||||||
}
|
}
|
||||||
|
|
@ -576,6 +584,7 @@ func main() {
|
||||||
*flExechookBackoff,
|
*flExechookBackoff,
|
||||||
hook.NewHookData(),
|
hook.NewHookData(),
|
||||||
log,
|
log,
|
||||||
|
execHookChannel,
|
||||||
)
|
)
|
||||||
go exechookRunner.Run(context.Background())
|
go exechookRunner.Run(context.Background())
|
||||||
}
|
}
|
||||||
|
|
@ -621,6 +630,22 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if initialSync {
|
if initialSync {
|
||||||
|
// Wait for hooks to complete at least once before checking whether to stop
|
||||||
|
// 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 {
|
||||||
|
log.Error(nil, "exec hook completed with error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if webHookChannel != nil {
|
||||||
|
webHookChannelFinishedSuccessfully:= <-webHookChannel
|
||||||
|
if !webHookChannelFinishedSuccessfully {
|
||||||
|
log.Error(nil, "web hook completed with error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine if git-sync should terminate
|
||||||
if *flOneTime {
|
if *flOneTime {
|
||||||
log.DeleteErrorFile()
|
log.DeleteErrorFile()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
|
|
|
||||||
|
|
@ -82,8 +82,8 @@ func (d *hookData) send(newHash string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHookRunner returns a new HookRunner
|
// NewHookRunner returns a new HookRunner
|
||||||
func NewHookRunner(hook Hook, backoff time.Duration, data *hookData, log *logging.Logger) *HookRunner {
|
func NewHookRunner(hook Hook, backoff time.Duration, data *hookData, log *logging.Logger, hasSucceededOnce chan bool) *HookRunner {
|
||||||
return &HookRunner{hook: hook, backoff: backoff, data: data, logger: log}
|
return &HookRunner{hook: hook, backoff: backoff, data: data, logger: log, hasCompletedOnce: hasSucceededOnce}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HookRunner struct
|
// HookRunner struct
|
||||||
|
|
@ -96,6 +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 chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send sends hash to hookdata
|
// Send sends hash to hookdata
|
||||||
|
|
@ -123,16 +125,29 @@ func (r *HookRunner) Run(ctx context.Context) {
|
||||||
if err := r.hook.Do(ctx, hash); err != nil {
|
if err := r.hook.Do(ctx, hash); err != nil {
|
||||||
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
|
||||||
|
r.sendCompletedOnceMessage(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)
|
||||||
break
|
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 r.hasCompletedOnce != nil {
|
||||||
|
r.hasCompletedOnce <- completedSuccessfully
|
||||||
|
close(r.hasCompletedOnce)
|
||||||
|
r.hasCompletedOnce = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updateHookRunCountMetric(name, status string) {
|
func updateHookRunCountMetric(name, status string) {
|
||||||
hookRunCount.WithLabelValues(name, status).Inc()
|
hookRunCount.WithLabelValues(name, status).Inc()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue