package ru.qatools.gridrouter.sessions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import ru.qatools.gridrouter.config.Version; import java.time.Duration; import java.time.temporal.Temporal; import static java.lang.String.format; import static java.time.ZonedDateTime.now; import static java.util.UUID.randomUUID; import static java.util.concurrent.TimeUnit.SECONDS; /** * @author Ilya Sadykov */ public class WaitAvailableBrowsersChecker implements AvailableBrowsersChecker { private static final Logger LOGGER = LoggerFactory.getLogger(WaitAvailableBrowsersChecker.class); @Value("${grid.router.queue.interval.seconds}") protected int queueWaitInterval; @Autowired protected StatsCounter statsCounter; @Value("${grid.router.queue.timeout.seconds}") protected int queueTimeout; public WaitAvailableBrowsersChecker() { } public WaitAvailableBrowsersChecker(int queueTimeout, int queueWaitInterval, StatsCounter statsCounter) { this.queueTimeout = queueTimeout; this.queueWaitInterval = queueWaitInterval; this.statsCounter = statsCounter; } @Override public void ensureFreeBrowsersAvailable(String user, String remoteHost, String browser, Version version) { int waitAttempt = 0; final String requestId = randomUUID().toString(); final Temporal waitingStarted = now(); final Duration maxWait = Duration.ofSeconds(queueTimeout); while (maxWait.compareTo(Duration.between(waitingStarted, now())) > 0 && (countSessions(user, browser, version)) >= version.getPermittedCount()) { try { onWait(user, browser, version, requestId, waitAttempt); Thread.sleep(SECONDS.toMillis(queueWaitInterval)); } catch (InterruptedException e) { LOGGER.error("Failed to sleep thread", e); } if (maxWait.compareTo(Duration.between(waitingStarted, now())) < 0) { onWaitTimeout(user, browser, version, requestId, waitAttempt); } } onWaitFinished(user, browser, version, requestId, waitAttempt); } protected void onWaitTimeout(String user, String browser, Version version, String requestId, int waitAttempt) { throw new WaitAvailableBrowserTimeoutException( format("Waiting for available browser of %s %s timed out for %s after %s attempts", browser, version.getNumber(), user, waitAttempt)); } protected void onWait(String user, String browser, Version version, String requestId, int waitAttempt) { LOGGER.info("[SESSION_WAIT_AVAILABLE_BROWSER] [{}] [{}] [{}] [{}] [{}]", user, browser, version.getNumber(), version.getPermittedCount(), ++waitAttempt); } protected void onWaitFinished(String user, String browser, Version version, String requestId, int waitAttempt) { LOGGER.info("[SESSION_WAIT_FINISHED] [{}] [{}] [{}] [{}] [{}]", user, browser, version.getNumber(), version.getPermittedCount(), ++waitAttempt); } protected int countSessions(String user, String browser, Version actualVersion) { return statsCounter.getSessionsCountForUserAndBrowser(user, browser, actualVersion.getNumber()); } }