Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: change the PagePool.Get method so that it returns an error for processing. #1050

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ func ExamplePage_pool() {
}

yourJob := func() {
page := pool.Get(create)
page := pool.MustGet(create)

// Put the instance back to the pool after we're done,
// so the instance can be reused by other goroutines.
Expand Down
2 changes: 1 addition & 1 deletion lib/examples/use-rod-like-chrome-extension/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func linkPreviewer(browser *rod.Browser) {

// Expose a function to the page to provide preview
page.MustExpose("getPreview", func(url gson.JSON) (interface{}, error) {
p := pool.Get(create)
p := pool.MustGet(create)
defer pool.Put(p)
p.MustNavigate(url.Str())
return base64.StdEncoding.EncodeToString(p.MustScreenshot()), nil
Expand Down
9 changes: 9 additions & 0 deletions must.go
Original file line number Diff line number Diff line change
Expand Up @@ -1155,3 +1155,12 @@ func (el *Element) MustGetXPath(optimized bool) string {
el.e(err)
return xpath
}

// MustGet a page from the pool. Use the [PagePool.Put] to make it reusable later.
func (pp PagePool) MustGet(create func() *Page) *Page {
p := <-pp
if p == nil {
p = create()
}
return p
}
62 changes: 60 additions & 2 deletions page_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -977,12 +977,70 @@ func TestPagePool(t *testing.T) {
g := setup(t)

pool := rod.NewPagePool(3)
defer pool.Cleanup(func(p *rod.Page) {
p.MustClose()
})
create := func() *rod.Page { return g.browser.MustPage() }
p := pool.Get(create)
p := pool.MustGet(create)
pool.Put(p)
pool.Cleanup(func(p *rod.Page) {
}

func TestPagePool_Get(t *testing.T) {
g := setup(t)

pool := rod.NewPagePool(3)
defer pool.Cleanup(func(p *rod.Page) {
p.MustClose()
})
create := func() (*rod.Page, error) {
b, err := g.browser.Incognito()
if err != nil {
return nil, err
}
return b.Page(proto.TargetCreateTarget{URL: ""})
}
p, err := pool.Get(create)
if err != nil {
t.Fatal(err)
}
pool.Put(p)
}

func TestPagePool_Get_Negative(t *testing.T) {
g := setup(t)
failContext, cancel := context.WithCancel(g.Context())
g.browser = g.browser.Context(failContext)
// manipulate browser canceled by another thread
pool := rod.NewPagePool(3)

defer pool.Cleanup(func(p *rod.Page) {
err := p.Close()
if err != nil {
t.Log(err)
}
})

create := func() (*rod.Page, error) {
b, err := g.browser.Incognito()
if err != nil {
return nil, err
}
return b.Page(proto.TargetCreateTarget{URL: ""})
}
p, err := pool.Get(create)
if err != nil {
t.Fatal(err)
}
pool.Put(p)

cancel()
p, err = pool.Get(create)
if err != nil {
t.Log(err)
} else {
pool.Put(p)
t.FailNow()
}
}

func TestPageUseNonExistSession(t *testing.T) {
Expand Down
23 changes: 15 additions & 8 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,26 +92,33 @@ func NewPagePool(limit int) PagePool {
return pp
}

// Get a page from the pool. Use the [PagePool.Put] to make it reusable later.
func (pp PagePool) Get(create func() *Page) *Page {
// Get a page from the pool, allow error. Use the [PagePool.Put] to make it reusable later.
func (pp PagePool) Get(create func() (*Page, error)) (*Page, error) {
p := <-pp
var err error
if p == nil {
p = create()
p, err = create()
if err != nil {
return nil, err
}
}
return p
return p, nil
}

// Put a page back to the pool.
func (pp PagePool) Put(p *Page) {
pp <- p
}

// Cleanup helper.
// Cleanup helper
func (pp PagePool) Cleanup(iteratee func(*Page)) {
for i := 0; i < cap(pp); i++ {
p := <-pp
if p != nil {
iteratee(p)
select {
case p := <-pp:
if p != nil {
iteratee(p)
}
default:
}
}
}
Expand Down
Loading