【Playwright for Python】スレッドセーフ(?)を実現したい
Q&A
Closed
発生している問題・エラー
page.on
で登録したイベントハンドラー上の処理において、処理が終わる前に新しいイベントが入ると処理が競合してしまいます。
該当するソースコード
from playwright.sync_api import sync_playwright, Playwright, Response
def response_handler(response: Response):
#...競合する処理
def main(playwright: Playwright):
browser = playwright.chromium.launch(headless=False)
page = browser.new_page()
page.goto("")
page.on("response", response_handler)
with sync_playwright() as playwright:
main(playwright)
自分で試したこと
1. whileでtime.sleep
おそらく同期APIでもasyncioを使用しているため全体がsleepしてしまう。
from playwright.sync_api import sync_playwright, Playwright, Response
import time
lock = False
def response_handler(response: Response):
global lock
while lock:
time.sleep(1)
lock = True
#...競合する処理
lock = False
def main(playwright: Playwright):
browser = playwright.chromium.launch(headless=False)
page = browser.new_page()
page.goto("")
page.on("response", response_handler)
with sync_playwright() as playwright:
main(playwright)
2. threadingのLock
随分的はずれなことをやっているというのは薄々わかっております。
from playwright.sync_api import sync_playwright, Playwright, Response
import threading
lock = threading.Lock()
async def response_handler(response: Response):
global lock
lock.acquire()
#...競合する処理
lock.release()
def main(playwright: Playwright):
browser = playwright.chromium.launch(headless=False)
page = browser.new_page()
page.goto("")
page.on("response", response_handler)
with sync_playwright() as playwright:
main(playwright)
3. whileでasyncio.sleep
こちらの記事を読んでasyncioについてはざっと理解しております。
最終的に行き着いたのが下のコードなのですが、そもそもresponse_handler
が呼ばれなくなってしまいました。
from playwright.sync_api import sync_playwright, Playwright, Response
import asyncio
lock = False
async def response_handler(response: Response):
global lock
while lock:
asyncio.sleep(1)
lock = True
#...競合する処理
lock = False
def main(playwright: Playwright):
browser = playwright.chromium.launch(headless=False)
page = browser.new_page()
page.goto("")
page.on("response", response_handler)
with sync_playwright() as playwright:
main(playwright)
非同期APIを使えばよかったのかもしれませんが、今更コードを全部書き直すのも不可能に近いのでなんとか同期APIで実現したいです。
どなたかわかる方、ご教授いただけましたら幸いです。
0