fix(restart): the self-relaunch waits for its parent's mutex
A database switch relaunches OpsLog, and the child regularly won the race against the old instance's teardown — so following the app's own instructions produced 'OpsLog is already running'. The relaunch now passes --relaunch, which gets the same 20-second mutex patience the post-update restart has always had. Opens the 0.27.6 block.
This commit is contained in:
@@ -2851,7 +2851,9 @@ func (a *App) RestartApp() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("locate executable: %w", err)
|
return fmt.Errorf("locate executable: %w", err)
|
||||||
}
|
}
|
||||||
cmd := exec.Command(exe)
|
// --relaunch: the child waits for OUR mutex instead of declaring us a
|
||||||
|
// duplicate — this instance is quitting, just not always fast enough.
|
||||||
|
cmd := exec.Command(exe, "--relaunch")
|
||||||
cmd.Dir = filepath.Dir(exe)
|
cmd.Dir = filepath.Dir(exe)
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
return fmt.Errorf("relaunch OpsLog: %w", err)
|
return fmt.Errorf("relaunch OpsLog: %w", err)
|
||||||
|
|||||||
@@ -1,4 +1,14 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "0.27.6",
|
||||||
|
"date": "",
|
||||||
|
"en": [
|
||||||
|
"Switching the settings database no longer shows “OpsLog is already running”: the automatic relaunch now waits for the closing instance to release its lock instead of racing it."
|
||||||
|
],
|
||||||
|
"fr": [
|
||||||
|
"Changer de base de réglages n’affiche plus « OpsLog is already running » : la relance automatique attend désormais que l’instance qui se ferme libère son verrou au lieu de la prendre de vitesse."
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "0.27.5",
|
"version": "0.27.5",
|
||||||
"date": "",
|
"date": "",
|
||||||
|
|||||||
@@ -48,14 +48,14 @@ func hasFlag(args []string, flag string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// acquireInstance grabs the single-instance mutex. On a normal launch it's a plain
|
// acquireInstance grabs the single-instance mutex. On a normal launch it's a plain
|
||||||
// try (fail → another OpsLog is running, so exit). On a --post-update relaunch the
|
// try (fail → another OpsLog is running, so exit). On a --post-update or
|
||||||
// previous instance may still be shutting down and holding the mutex, so retry for
|
// --relaunch start the previous instance may still be shutting down and holding
|
||||||
// a few seconds until it frees.
|
// the mutex, so retry for a few seconds until it frees.
|
||||||
func acquireInstance(postUpdate bool) bool {
|
func acquireInstance(wait bool) bool {
|
||||||
if acquireSingleInstance() {
|
if acquireSingleInstance() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if !postUpdate {
|
if !wait {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
deadline := time.Now().Add(20 * time.Second)
|
deadline := time.Now().Add(20 * time.Second)
|
||||||
@@ -90,7 +90,11 @@ func main() {
|
|||||||
// to free instead of bailing out. Then clear the old exe it left behind.
|
// to free instead of bailing out. Then clear the old exe it left behind.
|
||||||
bootLogLaunch()
|
bootLogLaunch()
|
||||||
postUpdate := hasFlag(os.Args[1:], "--post-update")
|
postUpdate := hasFlag(os.Args[1:], "--post-update")
|
||||||
if !acquireInstance(postUpdate) {
|
// A self-relaunch (database switch) races its own parent: the new process
|
||||||
|
// regularly wins the start against the old one's teardown, and the operator
|
||||||
|
// got "OpsLog is already running" for following instructions. Same patience
|
||||||
|
// as post-update.
|
||||||
|
if !acquireInstance(postUpdate || hasFlag(os.Args[1:], "--relaunch")) {
|
||||||
// SAID, not merely done. This exit is correct — a second instance would
|
// SAID, not merely done. This exit is correct — a second instance would
|
||||||
// fight the first over the rig — but it happened in total silence: no
|
// fight the first over the rig — but it happened in total silence: no
|
||||||
// window, no data folder, no log, which is indistinguishable from a
|
// window, no data folder, no log, which is indistinguishable from a
|
||||||
|
|||||||
Reference in New Issue
Block a user