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

[Question]: Is playwhright-go thread-safe if multiple instances are created in separate go routines? #492

Open
martingrzzler opened this issue Sep 30, 2024 · 3 comments

Comments

@martingrzzler
Copy link

I'm using this awesome library for web scraping but when running browsers in parallel I get random crashes.
So this might be because the library is not thread-safe. In the following example I create two different instances of Chrome with playwhright.Run. Is this save to do?

package main

import (
	"sync"

	"github.com/crawler/internal/crawl"
)

func main() {

	wg := sync.WaitGroup{}

	wg.Add(1)
	go func() {
		defer wg.Done()
                // creates a new instances with playwhright.Run
		b1, err := crawl.LauchBrowser(crawl.LaunchOptions{
			Headless: false,
		})
		if err != nil {
			panic("failed to launch browser" + err.Error())
		}
		for i := 0; i < 10; i++ {
			p, err := crawl.NewPage(b1)
			if err != nil {
				panic("failed to create new page" + err.Error())
			}

			_, err = crawl.ScrapeHomePage(p, "https://google.com")
			if err != nil {
				panic("failed to scrape home page" + err.Error())
			}

			err = p.Context().Close()
			if err != nil {
				panic("failed to close context" + err.Error())
			}
		}

	}()

	wg.Add(1)
	go func() {
		b2, err := crawl.LauchBrowser(crawl.LaunchOptions{
			Headless: false,
		})
		if err != nil {
			panic("failed to launch browser" + err.Error())
		}
		defer wg.Done()

		for i := 0; i < 10; i++ {
			p, err := crawl.NewPage(b2)
			if err != nil {
				panic("failed to create new page" + err.Error())
			}

			_, err = crawl.ScrapeHomePage(p, "https://example.com")
			if err != nil {
				panic("failed to scrape home page" + err.Error())
			}

			err = p.Context().Close()
			if err != nil {
				panic("failed to close context" + err.Error())
			}

		}
	}()

	wg.Wait()
}
@canstand
Copy link
Collaborator

canstand commented Oct 1, 2024

What you should do is create a new BrowserContext per goroutine, instead of launching multiple browsers.

@martingrzzler
Copy link
Author

@canstand So using multiple BrowserContext in each goroutine is safe then?
I'm asking because of this comment: #119 (comment)

@canstand
Copy link
Collaborator

canstand commented Oct 2, 2024

It can be considered safe for your use case. BrowserContext is isolated from each other, which is equivalent to opening multiple browser windows and each has its own temporary data directory and profile.

You need to be careful to avoid deadlocks like #481 and #391 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants