StandardPlaywrightPageRenderer.java
package net.sasasin.sreader.service.extraction.browser;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.Page;
import java.net.URI;
import java.util.Objects;
import net.sasasin.sreader.config.FeedReaderProperties;
/**
* Renders a page with a short-lived BrowserContext from the shared regular Browser. One context per
* render.
*/
final class StandardPlaywrightPageRenderer {
private final FeedReaderProperties.Playwright settings;
private final PlaywrightRuntime runtime;
private final PlaywrightPageNavigator navigator;
StandardPlaywrightPageRenderer(
FeedReaderProperties.Playwright settings,
PlaywrightRuntime runtime,
PlaywrightPageNavigator navigator) {
this.settings = Objects.requireNonNull(settings, "settings must not be null");
this.runtime = Objects.requireNonNull(runtime, "runtime must not be null");
this.navigator = Objects.requireNonNull(navigator, "navigator must not be null");
}
RenderedPage render(URI requestedUri) {
Objects.requireNonNull(requestedUri, "requestedUri must not be null");
BrowserContext context =
runtime
.browser()
.newContext(
new Browser.NewContextOptions()
.setViewportSize(settings.viewportWidth(), settings.viewportHeight()));
RuntimeException primary = null;
RenderedPage result = null;
try {
Page page = context.newPage();
navigator.navigate(page, requestedUri);
navigator.waitNetworkIdleBestEffort(page);
result = navigator.capture(page, requestedUri);
} catch (RuntimeException e) {
primary = e;
} finally {
primary = PlaywrightCloseSupport.close(primary, context::close);
}
if (primary != null) {
throw primary;
}
return result;
}
/**
* Opens one short-lived standard context/page session, runs {@code work}, and always closes the
* session. Primary work failures are preserved when close also fails.
*
* <p>Must be called only while holding the {@link PlaywrightHtmlSource} monitor.
*/
<T> T withSession(PlaywrightSessionWork<T> work) {
Objects.requireNonNull(work, "work must not be null");
PlaywrightArticlePageSession session =
PlaywrightArticlePageSession.open(runtime, settings, navigator);
RuntimeException primary = null;
T result = null;
try {
result = work.apply(session);
} catch (RuntimeException e) {
primary = e;
} finally {
primary = PlaywrightCloseSupport.close(primary, session::close);
}
if (primary != null) {
throw primary;
}
return result;
}
}