All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.hyperfoil.http.HttpRequestPool Maven / Gradle / Ivy

There is a newer version: 0.27.1
Show newest version
package io.hyperfoil.http;

import io.hyperfoil.api.collection.LimitedPool;
import io.hyperfoil.api.config.Scenario;
import io.hyperfoil.api.session.Session;
import io.hyperfoil.core.data.LimitedPoolResource;
import io.hyperfoil.http.api.HttpRequest;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;

public class HttpRequestPool extends LimitedPoolResource {
   private static final Logger log = LoggerFactory.getLogger(HttpRequestPool.class);
   private static final boolean trace = log.isTraceEnabled();
   public static final Session.ResourceKey> KEY = new Key<>();

   public HttpRequestPool(Scenario scenario, Session session) {
      super(scenario.maxRequests(), HttpRequest.class, () -> new HttpRequest(session));
   }

   public static LimitedPool get(Session session) {
      return session.getResource(KEY);
   }

   @Override
   public void onSessionReset(Session session) {
      if (!isFull()) {
         // We can't guarantee that requests will be back in session's requestPool when it terminates
         // because if the requests did timeout (calling handlers and eventually letting the session terminate)
         // it might still be held in the connection.
         for (HttpRequest request : (HttpRequest[]) originalObjects) {
            if (!request.isCompleted()) {
               log.warn("#{} Session completed with requests in-flight!", session.uniqueId());
               break;
            }
         }
         cancelRequests();
      }
      super.onSessionReset(session);
   }

   private void cancelRequests() {
      // We need to close all connections used to ongoing requests, despite these might
      // carry requests from independent phases/sessions
      for (HttpRequest request : (HttpRequest[]) originalObjects) {
         if (!request.isCompleted()) {
            // When one of the handlers calls Session.stop() it may terminate the phase completely,
            // sending stats before recording the invalid request in HttpResponseHandlersImpl.handleEnd().
            // That's why we record it here instead and mark the request as completed (to recording the stats twice)
            if (!request.isValid()) {
               request.statistics().addInvalid(request.startTimestampMillis());
            }
            if (trace) {
               log.trace("Canceling request on {}", request.connection());
            }
            request.setCompleting();
            if (request.connection() != null) {
               request.connection().close();
            }
            if (!request.isCompleted()) {
               // Connection.close() cancels everything in flight but if this is called
               // from handleEnd() the request is not in flight anymore
               log.trace("#{} Connection close did not complete the request.", request.session != null ? request.session.uniqueId() : 0);
               request.setCompleted();
               request.release();
            }
         }
      }
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy