@Override public final Connection createConnection() throws AmqpException { Assert.state( !this.stopped, "The ApplicationContext is closed and the ConnectionFactory can no longer create connections."); synchronized (this.connectionMonitor) { if (this.cacheMode == CacheMode.CHANNEL) { if (this.connection == null) { this.connection = new ChannelCachingConnectionProxy(super.createBareConnection()); // invoke the listener *after* this.connection is assigned getConnectionListener().onCreate(connection); this.checkoutPermits.put(this.connection, new Semaphore(this.channelCacheSize)); } return this.connection; } else if (this.cacheMode == CacheMode.CONNECTION) { ChannelCachingConnectionProxy connection = null; while (connection == null && !this.idleConnections.isEmpty()) { connection = this.idleConnections.poll(); if (connection != null) { if (!connection.isOpen()) { if (logger.isDebugEnabled()) { logger.debug("Removing closed connection '" + connection + "'"); } connection.notifyCloseIfNecessary(); this.openConnections.remove(connection); this.openConnectionNonTransactionalChannels.remove(connection); this.openConnectionTransactionalChannels.remove(connection); this.checkoutPermits.remove(connection); connection = null; } } } if (connection == null) { connection = new ChannelCachingConnectionProxy(super.createBareConnection()); getConnectionListener().onCreate(connection); if (logger.isDebugEnabled()) { logger.debug("Adding new connection '" + connection + "'"); } this.openConnections.add(connection); this.openConnectionNonTransactionalChannels.put( connection, new LinkedList<ChannelProxy>()); this.openConnectionTransactionalChannels.put(connection, new LinkedList<ChannelProxy>()); this.checkoutPermits.put(connection, new Semaphore(this.channelCacheSize)); } else { if (logger.isDebugEnabled()) { logger.debug("Obtained connection '" + connection + "' from cache"); } } return connection; } } return null; }
private Channel createBareChannel( ChannelCachingConnectionProxy connection, boolean transactional) { if (this.cacheMode == CacheMode.CHANNEL) { if (this.connection == null || !this.connection.isOpen()) { synchronized (this.connectionMonitor) { if (this.connection != null && !this.connection.isOpen()) { this.connection.notifyCloseIfNecessary(); this.checkoutPermits.remove(this.connection); } if (this.connection == null || !this.connection.isOpen()) { this.connection = null; createConnection(); } } } return doCreateBareChannel(this.connection, transactional); } else if (this.cacheMode == CacheMode.CONNECTION) { if (!connection.isOpen()) { synchronized (connectionMonitor) { this.openConnectionNonTransactionalChannels.get(connection).clear(); this.openConnectionTransactionalChannels.get(connection).clear(); connection.notifyCloseIfNecessary(); ChannelCachingConnectionProxy newConnection = (ChannelCachingConnectionProxy) createConnection(); /* * Applications already have a reference to the proxy, so we steal the new (or idle) connection's * target and remove the connection from the open list. */ connection.target = newConnection.target; connection.closeNotified.set(false); this.openConnections.remove(newConnection); } } return doCreateBareChannel(connection, transactional); } return null; }
private Channel getChannel(ChannelCachingConnectionProxy connection, boolean transactional) { if (this.channelCheckoutTimeout > 0) { Semaphore checkoutPermits = this.checkoutPermits.get(connection); if (checkoutPermits != null) { try { if (!checkoutPermits.tryAcquire(this.channelCheckoutTimeout, TimeUnit.MILLISECONDS)) { throw new AmqpTimeoutException("No available channels"); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new AmqpTimeoutException("Interrupted while acquiring a channel", e); } } } LinkedList<ChannelProxy> channelList; if (this.cacheMode == CacheMode.CHANNEL) { channelList = transactional ? this.cachedChannelsTransactional : this.cachedChannelsNonTransactional; } else { channelList = transactional ? this.openConnectionTransactionalChannels.get(connection) : this.openConnectionNonTransactionalChannels.get(connection); } if (channelList == null) { channelList = new LinkedList<ChannelProxy>(); if (transactional) { this.openConnectionTransactionalChannels.put(connection, channelList); } else { this.openConnectionNonTransactionalChannels.put(connection, channelList); } } ChannelProxy channel = null; if (connection.isOpen()) { synchronized (channelList) { while (!channelList.isEmpty()) { channel = channelList.removeFirst(); if (logger.isTraceEnabled()) { logger.trace(channel + " retrieved from cache"); } if (channel.isOpen()) { break; } else { try { Channel target = channel.getTargetChannel(); if (target != null) { target.close(); // to remove it from auto-recovery if so configured } } catch (AlreadyClosedException e) { if (logger.isTraceEnabled()) { logger.trace(channel + " is already closed"); } } catch (IOException e) { if (logger.isDebugEnabled()) { logger.debug("Unexpected Exception closing channel " + e.getMessage()); } } catch (TimeoutException e) { if (logger.isWarnEnabled()) { logger.warn("TimeoutException closing channel " + e.getMessage()); } } channel = null; } } } if (channel != null) { if (logger.isTraceEnabled()) { logger.trace("Found cached Rabbit Channel: " + channel.toString()); } } } if (channel == null) { channel = getCachedChannelProxy(connection, channelList, transactional); } return channel; }