PlaywrightRuntime.java
package net.sasasin.sreader.service.extraction.browser;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Playwright;
import java.util.Objects;
import net.sasasin.sreader.config.FeedReaderProperties;
/**
* Owns the Playwright process and the regular Chromium {@link Browser}.
*
* <p>Not a public concurrent API: all access is expected to be serialized by {@link
* PlaywrightHtmlSource}.
*/
final class PlaywrightRuntime {
private final FeedReaderProperties.Playwright settings;
private final PlaywrightFactory playwrightFactory;
private Playwright playwright;
private Browser browser;
private volatile boolean running;
PlaywrightRuntime(FeedReaderProperties.Playwright settings, PlaywrightFactory playwrightFactory) {
this.settings = Objects.requireNonNull(settings, "settings must not be null");
this.playwrightFactory =
Objects.requireNonNull(playwrightFactory, "playwrightFactory must not be null");
}
void start() {
if (running) {
return;
}
Playwright created = null;
try {
created = playwrightFactory.create();
Browser launched =
created
.chromium()
.launch(
new BrowserType.LaunchOptions()
.setChannel("chromium")
.setHeadless(settings.headless()));
this.playwright = created;
this.browser = launched;
this.running = true;
} catch (RuntimeException startupFailure) {
this.browser = null;
this.playwright = null;
this.running = false;
if (created != null) {
RuntimeException primary = PlaywrightCloseSupport.close(startupFailure, created::close);
PlaywrightCloseSupport.throwIfPresent(primary);
}
throw startupFailure;
}
}
Browser browser() {
ensureStarted();
return browser;
}
boolean isRunning() {
return running;
}
void stop() {
if (!running && browser == null && playwright == null) {
return;
}
RuntimeException primary = null;
if (browser != null) {
Browser toClose = browser;
browser = null;
primary = PlaywrightCloseSupport.close(primary, toClose::close);
}
if (playwright != null) {
Playwright toClose = playwright;
playwright = null;
primary = PlaywrightCloseSupport.close(primary, toClose::close);
}
running = false;
PlaywrightCloseSupport.throwIfPresent(primary);
}
private void ensureStarted() {
if (!running) {
start();
}
}
}