private async Task <HttpResponseMessage> ProcessSessionRequest(HttpContext context) { var retriesLeft = _routerConfig.Value.SessionRetryCount; var retryTimeout = _routerConfig.Value.SessionRetryTimeout; var body = await ReadRequestBody(context); _logger.LogDebug("Request: {0}", body); if (string.IsNullOrWhiteSpace(body)) { _logger.LogDebug("Session request with empty body"); } var caps = Caps.Parse(body, _logger); _logger.LogInformation($"New session request from {context.Connection.RemoteIpAddress}"); _logger.LogDebug($"Requested caps: {JsonSerializer.Serialize(caps)}"); var sessionTimeout = GetSessionTimeout(caps); do { var worker = await _balancer.GetNext(new Request(caps)); var sessionEndpoint = new Uri(new Uri(worker.Host.AbsoluteUri.TrimEnd('/') + "/"), "session"); var initResponse = await context .ForwardTo(sessionEndpoint) .AddXForwardedHeaders() .Send(); if (initResponse.IsSuccessStatusCode) { var responseBody = await initResponse.Content.ReadAsStringAsync(); var seleniumResponse = JsonDocument.Parse(responseBody); var sessionId = seleniumResponse.RootElement.GetProperty("value").GetProperty("sessionId") .GetString(); _logger.LogInformation($"New session: {sessionId} on host '{worker.Host}'"); _sessions.Add(sessionId, new SessionData(sessionEndpoint, worker.Host, worker, sessionTimeout)); Touch(sessionId, worker.Host); return(initResponse); } else if (--retriesLeft <= 0) { _logger.LogError("Failed to process /session request after 3 retries"); return(initResponse); } else { _logger.LogWarning("Failed to get response from {0}, retrying in 10s", worker.Host); worker.Dispose(); // TODO consider _registry.ReleaseHost(worker); await Task.Delay(retryTimeout); } } while (true); }