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

io.gatling.http.client.pool.CoalescingChannelPool Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2011-2024 GatlingCorp (https://gatling.io)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.gatling.http.client.pool;

import io.gatling.http.client.ssl.Tls;
import io.netty.channel.Channel;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.function.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

final class CoalescingChannelPool {
  private static final Logger LOGGER = LoggerFactory.getLogger(CoalescingChannelPool.class);

  // FIXME Queue or Set?
  private final Map, Queue>>> channels =
      new HashMap<>(ChannelPool.INITIAL_CLIENT_MAP_SIZE);

  private final Map>> cleanUpMap =
      new HashMap<>(ChannelPool.INITIAL_CLIENT_MAP_SIZE);

  private Map, Queue>> clientChannels(long clientId) {
    return channels.computeIfAbsent(
        clientId, k -> new HashMap<>(ChannelPool.INITIAL_KEY_PER_CLIENT_MAP_SIZE));
  }

  private Map> clientCleanUpMap(long clientId) {
    return cleanUpMap.computeIfAbsent(
        clientId, k -> new HashMap<>(ChannelPool.INITIAL_KEY_PER_CLIENT_MAP_SIZE));
  }

  void addEntry(
      long clientId, IpAndPort ipAndPort, Set subjectAlternativeNames, Channel channel) {
    Map, Queue>> clientChannels =
        clientChannels(clientId);
    Map.Entry, Queue> entry = clientChannels.get(ipAndPort);
    Queue channels;
    if (entry == null) {
      channels = new ArrayDeque<>(ChannelPool.INITIAL_CHANNEL_QUEUE_SIZE);
      channels.add(channel);
      clientChannels.put(
          ipAndPort, new AbstractMap.SimpleEntry<>(subjectAlternativeNames, channels));
    } else {
      channels = entry.getValue();
      entry.getValue().offer(channel);
    }

    clientCleanUpMap(clientId).put(channel, channels);
  }

  Channel getCoalescedChannel(
      long clientId,
      String domain,
      List addresses,
      Function onCandidate) {
    for (InetSocketAddress address : addresses) {
      IpAndPort ipAndPort = new IpAndPort(address.getAddress().getAddress(), address.getPort());
      Map.Entry, Queue> entry = clientChannels(clientId).get(ipAndPort);
      if (entry != null) {
        for (String subjectAlternativeName : entry.getKey()) {
          if (Tls.isCertificateAuthoritative(subjectAlternativeName, domain)) {
            for (Channel channel : entry.getValue()) {
              if (channel.isActive() && onCandidate.apply(channel)) {
                return channel;
              }
            }
          }
        }
      }
    }
    return null;
  }

  void deleteIdleEntry(long clientId, Channel channel) {
    Map> clientCleanUpMap = cleanUpMap.get(clientId);
    if (clientCleanUpMap != null) {
      Queue channels = clientCleanUpMap.get(channel);
      if (channels != null) {
        channels.remove(channel);
        clientCleanUpMap.remove(channel);
      }
    }
  }

  void deleteClientEntries(long clientId) {
    channels.remove(clientId);
    cleanUpMap.remove(clientId);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy