Clear the tabs open in browser
Rod Version: v0.107.3
How I can clear or close the non used tabs in the browser after say x minute.
Problem: I initiate a browser at the start of the program
u := launcher.New().
UserDataDir("path").
Headless(true).
MustLaunch()
And whenever a request comes I open a new page inside the above launcher
page := rod.New().ControlURL(uc.launcher).MustConnect().MustPage(url)
defer page.MustClose()
But due to some reason, the page doesn't get close like the failure of method or a long wait for the page to open or any response from the page due to which the system memory starts increasing as the request keeps on coming.
Is there any way I can close this open non-required pages/tabs anyway after x minute (using cron)?
Please fix the format of your markdown:
7 MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines [Context: "```"]
7 MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
15 MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines [Context: "```"]
15 MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
24 MD012/no-multiple-blanks Multiple consecutive blank lines [Expected: 1; Actual: 2]
25 MD012/no-multiple-blanks Multiple consecutive blank lines [Expected: 1; Actual: 3]
generated by check-issue
for _, p := range browser.MustPages() {
p.MustClose()
}
to @vipulsingh24
I do not think it is good idea to leave the processes like that, especially the problem mostly comes from the chrome remote protocol itself. Since rod is a wrapper, it will become a bit harder than you what you might expected...
However, if you insist, you may write some functions as...
For example... following pattern will call close function after some time (from the example, 10 min)
func newPage(b *rod.Browser) *rod.Page {
// as usual
p := b.MustPage()
// launch a go-routine that will call the close func
go func(page *rod.Page) {
// set timer for close
timer := time.After(time.Minute * 10)
// wait
<- timer
if err := page.Close(); err != nil {
fmt.Printf("failed to close page: %+v\n", err.Error())
}
}(p)
// use the page.
return p
}
As you may have noticed, problem arises when you need to close your application before those waits.
I recommend use combination of context package and sync package (specifically, sync.WaitGroup.) If you use parent context to propagate cancellation... it may look something like this.
func newPage(browser *rod.Browser, parentCtx context.Context, wg *sync.WaitGroup) *rod.Page {
p := browser.MustPage()
go func(page *rod.Page, pCtx context.Context, pWg *sync.WaitGroup) {
// report to parent wg that the page is closed (or tried at best)
defer pWg.Done()
timer := time.After(time.Minute * 10)
// wait until either timer or parent context is closed
select {
case <-pCtx.Done():
case <-timer:
break
}
if err := page.Close(); err != nil {
fmt.Printf("failed to close page: %+v\n", err.Error())
} else {
fmt.Printf("closed %+v\n", page.TargetID)
}
}(p, parentCtx, wg)
return p
}