Skip to content

Commit 2d3e61f

Browse files
zeoxiscabestmountain
andauthored
Feat: Add the PagePool.TryGet method while it returns an error for processing. (#1051)
* PagePool add TryGet to deal error that Page() returns. * modify tryget * Add BrowserPool TryGet test * test coverage * go fmt * go fmt * pool.Get -> pool.MustGet; pool.Get allow error --------- Co-authored-by: bestmountain <[email protected]>
1 parent 5a690b3 commit 2d3e61f

File tree

6 files changed

+155
-19
lines changed

6 files changed

+155
-19
lines changed

browser_test.go

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package rod_test
22

33
import (
4+
"context"
45
"errors"
56
"fmt"
67
"net/http"
@@ -442,13 +443,64 @@ func TestBrowserConnectFailure(t *testing.T) {
442443
func TestBrowserPool(_ *testing.T) {
443444
pool := rod.NewBrowserPool(3)
444445
create := func() *rod.Browser { return rod.New().MustConnect() }
445-
b := pool.Get(create)
446+
b := pool.MustGet(create)
446447
pool.Put(b)
447448
pool.Cleanup(func(p *rod.Browser) {
448449
p.MustClose()
449450
})
450451
}
451452

453+
func TestBrowserPool_TryGet(t *testing.T) {
454+
pool := rod.NewBrowserPool(3)
455+
defer pool.Cleanup(func(p *rod.Browser) {
456+
err := p.Close()
457+
if err != nil {
458+
t.Log(err)
459+
}
460+
})
461+
create := func() (*rod.Browser, error) {
462+
b := rod.New()
463+
err := b.Connect()
464+
return b, err
465+
}
466+
for i := 0; i < 4; i++ {
467+
b, err := pool.Get(create)
468+
if err != nil {
469+
t.Fatal(err)
470+
}
471+
pool.Put(b)
472+
}
473+
}
474+
475+
func TestBrowserPool_TryGet_Negative(t *testing.T) {
476+
pool := rod.NewBrowserPool(3)
477+
defer pool.Cleanup(func(p *rod.Browser) {
478+
err := p.Close()
479+
if err != nil {
480+
t.Log(err)
481+
}
482+
})
483+
ctx, cancel := context.WithCancel(context.Background())
484+
create := func() (*rod.Browser, error) {
485+
b := rod.New().Context(ctx)
486+
err := b.Connect()
487+
return b, err
488+
}
489+
b, err := pool.Get(create)
490+
if err != nil {
491+
t.Fatal(err)
492+
}
493+
pool.Put(b)
494+
cancel()
495+
b, err = pool.Get(create)
496+
if err != nil {
497+
t.Log(err)
498+
} else {
499+
pool.Put(b)
500+
t.FailNow()
501+
}
502+
}
503+
452504
func TestOldBrowser(t *testing.T) {
453505
t.Skip()
454506

examples_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ func ExamplePage_pool() {
582582
}
583583

584584
yourJob := func() {
585-
page := pool.Get(create)
585+
page := pool.MustGet(create)
586586

587587
// Put the instance back to the pool after we're done,
588588
// so the instance can be reused by other goroutines.
@@ -632,7 +632,7 @@ func ExampleBrowser_pool() {
632632
defer wg.Done()
633633

634634
// Get a browser instance from the pool
635-
browser := pool.Get(create)
635+
browser := pool.MustGet(create)
636636

637637
// Put the instance back to the pool after we're done,
638638
// so the instance can be reused by other goroutines.

lib/examples/use-rod-like-chrome-extension/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func linkPreviewer(browser *rod.Browser) {
5151

5252
// Expose a function to the page to provide preview
5353
page.MustExpose("getPreview", func(url gson.JSON) (interface{}, error) {
54-
p := pool.Get(create)
54+
p := pool.MustGet(create)
5555
defer pool.Put(p)
5656
p.MustNavigate(url.Str())
5757
return base64.StdEncoding.EncodeToString(p.MustScreenshot()), nil

must.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,3 +1155,21 @@ func (el *Element) MustGetXPath(optimized bool) string {
11551155
el.e(err)
11561156
return xpath
11571157
}
1158+
1159+
// MustGet a page from the pool. Use the [PagePool.Put] to make it reusable later.
1160+
func (pp PagePool) MustGet(create func() *Page) *Page {
1161+
p := <-pp
1162+
if p == nil {
1163+
p = create()
1164+
}
1165+
return p
1166+
}
1167+
1168+
// MustGet a browser from the pool. Use the [BrowserPool.Put] to make it reusable later.
1169+
func (bp BrowserPool) MustGet(create func() *Browser) *Browser {
1170+
p := <-bp
1171+
if p == nil {
1172+
p = create()
1173+
}
1174+
return p
1175+
}

page_test.go

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -978,13 +978,73 @@ func TestPagePool(t *testing.T) {
978978

979979
pool := rod.NewPagePool(3)
980980
create := func() *rod.Page { return g.browser.MustPage() }
981-
p := pool.Get(create)
981+
p := pool.MustGet(create)
982982
pool.Put(p)
983983
pool.Cleanup(func(p *rod.Page) {
984984
p.MustClose()
985985
})
986986
}
987987

988+
func TestPagePool_Get(t *testing.T) {
989+
g := setup(t)
990+
991+
pool := rod.NewPagePool(3)
992+
defer pool.Cleanup(func(p *rod.Page) {
993+
p.MustClose()
994+
})
995+
create := func() (*rod.Page, error) {
996+
b, err := g.browser.Incognito()
997+
if err != nil {
998+
return nil, err
999+
}
1000+
return b.Page(proto.TargetCreateTarget{URL: ""})
1001+
}
1002+
for i := 0; i < 4; i++ {
1003+
p, err := pool.Get(create)
1004+
if err != nil {
1005+
t.Fatal(err)
1006+
}
1007+
pool.Put(p)
1008+
}
1009+
}
1010+
1011+
func TestPagePool_Get_Negative(t *testing.T) {
1012+
g := setup(t)
1013+
failContext, cancel := context.WithCancel(g.Context())
1014+
g.browser = g.browser.Context(failContext)
1015+
// manipulate browser canceled by another thread
1016+
pool := rod.NewPagePool(3)
1017+
1018+
defer pool.Cleanup(func(p *rod.Page) {
1019+
err := p.Close()
1020+
if err != nil {
1021+
t.Log(err)
1022+
}
1023+
})
1024+
1025+
create := func() (*rod.Page, error) {
1026+
b, err := g.browser.Incognito()
1027+
if err != nil {
1028+
return nil, err
1029+
}
1030+
return b.Page(proto.TargetCreateTarget{URL: ""})
1031+
}
1032+
p, err := pool.Get(create)
1033+
if err != nil {
1034+
t.Fatal(err)
1035+
}
1036+
pool.Put(p)
1037+
1038+
cancel()
1039+
p, err = pool.Get(create)
1040+
if err != nil {
1041+
t.Log(err)
1042+
} else {
1043+
pool.Put(p)
1044+
t.FailNow()
1045+
}
1046+
}
1047+
9881048
func TestPageUseNonExistSession(t *testing.T) {
9891049
g := setup(t)
9901050

utils.go

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,13 @@ func NewPagePool(limit int) PagePool {
9292
return pp
9393
}
9494

95-
// Get a page from the pool. Use the [PagePool.Put] to make it reusable later.
96-
func (pp PagePool) Get(create func() *Page) *Page {
95+
// Get a page from the pool, allow error. Use the [PagePool.Put] to make it reusable later.
96+
func (pp PagePool) Get(create func() (*Page, error)) (*Page, error) {
9797
p := <-pp
9898
if p == nil {
99-
p = create()
99+
return create()
100100
}
101-
return p
101+
return p, nil
102102
}
103103

104104
// Put a page back to the pool.
@@ -109,9 +109,12 @@ func (pp PagePool) Put(p *Page) {
109109
// Cleanup helper.
110110
func (pp PagePool) Cleanup(iteratee func(*Page)) {
111111
for i := 0; i < cap(pp); i++ {
112-
p := <-pp
113-
if p != nil {
114-
iteratee(p)
112+
select {
113+
case p := <-pp:
114+
if p != nil {
115+
iteratee(p)
116+
}
117+
default:
115118
}
116119
}
117120
}
@@ -131,13 +134,13 @@ func NewBrowserPool(limit int) BrowserPool {
131134
return pp
132135
}
133136

134-
// Get a browser from the pool. Use the [BrowserPool.Put] to make it reusable later.
135-
func (bp BrowserPool) Get(create func() *Browser) *Browser {
137+
// Get a browser from the pool, allow error. Use the [BrowserPool.Put] to make it reusable later.
138+
func (bp BrowserPool) Get(create func() (*Browser, error)) (*Browser, error) {
136139
p := <-bp
137140
if p == nil {
138-
p = create()
141+
return create()
139142
}
140-
return p
143+
return p, nil
141144
}
142145

143146
// Put a browser back to the pool.
@@ -148,9 +151,12 @@ func (bp BrowserPool) Put(p *Browser) {
148151
// Cleanup helper.
149152
func (bp BrowserPool) Cleanup(iteratee func(*Browser)) {
150153
for i := 0; i < cap(bp); i++ {
151-
p := <-bp
152-
if p != nil {
153-
iteratee(p)
154+
select {
155+
case p := <-bp:
156+
if p != nil {
157+
iteratee(p)
158+
}
159+
default:
154160
}
155161
}
156162
}

0 commit comments

Comments
 (0)