From 7fae9b366381f7af72e523547ab5b027b3092436 Mon Sep 17 00:00:00 2001 From: kvii <56432636+kvii@users.noreply.github.com> Date: Sat, 29 Jul 2023 15:26:50 +0800 Subject: [PATCH] Add a flag to prevent launching twice. (#910) * Add a flag to prevent launching twice. * fix go version bug --- lib/launcher/error.go | 6 ++++++ lib/launcher/launcher.go | 13 +++++++++++++ lib/launcher/launcher_test.go | 14 ++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 lib/launcher/error.go diff --git a/lib/launcher/error.go b/lib/launcher/error.go new file mode 100644 index 00000000..fd643b4c --- /dev/null +++ b/lib/launcher/error.go @@ -0,0 +1,6 @@ +package launcher + +import "errors" + +// ErrAlreadyLaunched is an error that indicates the launcher has already been launched. +var ErrAlreadyLaunched = errors.New("already launched") diff --git a/lib/launcher/launcher.go b/lib/launcher/launcher.go index fe5d4db2..b711d113 100644 --- a/lib/launcher/launcher.go +++ b/lib/launcher/launcher.go @@ -13,6 +13,7 @@ import ( "path/filepath" "sort" "strings" + "sync/atomic" "github.com/go-rod/rod/lib/defaults" "github.com/go-rod/rod/lib/launcher/flags" @@ -39,6 +40,8 @@ type Launcher struct { managed bool serviceURL string + + isLaunched int32 // zero means not launched } // New returns the default arguments to start browser. @@ -377,7 +380,13 @@ func (l *Launcher) MustLaunch() string { // Launch a standalone temp browser instance and returns the debug url. // bin and profileDir are optional, set them to empty to use the default values. // If you want to reuse sessions, such as cookies, set the [Launcher.UserDataDir] to the same location. +// +// Please note launcher can only be used once. func (l *Launcher) Launch() (string, error) { + if l.hasLaunched() { + return "", ErrAlreadyLaunched + } + defer l.ctxCancel() bin, err := l.getBin() @@ -430,6 +439,10 @@ func (l *Launcher) Launch() (string, error) { return ResolveURL(u) } +func (l *Launcher) hasLaunched() bool { + return !atomic.CompareAndSwapInt32(&l.isLaunched, 0, 1) +} + func (l *Launcher) setupCmd(cmd *exec.Cmd) { l.osSetupCmd(cmd) diff --git a/lib/launcher/launcher_test.go b/lib/launcher/launcher_test.go index 06ce7a53..7dc4f00f 100644 --- a/lib/launcher/launcher_test.go +++ b/lib/launcher/launcher_test.go @@ -310,3 +310,17 @@ func TestBrowserDownloadErr(t *testing.T) { }} g.Err(b.Download()) } + +func TestLaunchMultiTimes(t *testing.T) { + g := setup(t) + + // first time launch, success. + l := launcher.New() + u, e := l.Launch() + g.Neq(u, "") + g.E(e) + + // second time launch, failed with ErrAlreadyLaunched. + _, e = l.Launch() + g.Eq(e, launcher.ErrAlreadyLaunched) +}