/** This method is synchronized because we want it to be atomic with the cursors being used */ private long checkMinPage(List<PageSubscription> cursorList) { long minPage = Long.MAX_VALUE; for (PageSubscription cursor : cursorList) { long firstPage = cursor.getFirstPage(); if (log.isDebugEnabled()) { log.debug( this.pagingStore.getAddress() + " has a cursor " + cursor + " with first page=" + firstPage); } if (firstPage < minPage) { minPage = firstPage; } } if (log.isDebugEnabled()) { log.debug(this.pagingStore.getAddress() + " has minPage=" + minPage); } return minPage; }
public synchronized PageSubscription createSubscription( long cursorID, Filter filter, boolean persistent) { if (log.isDebugEnabled()) { log.debug( this.pagingStore.getAddress() + " creating subscription " + cursorID + " with filter " + filter, new Exception("trace")); } PageSubscription activeCursor = activeCursors.get(cursorID); if (activeCursor != null) { throw new IllegalStateException("Cursor " + cursorID + " had already been created"); } activeCursor = new PageSubscriptionImpl( this, pagingStore, storageManager, executor, filter, cursorID, persistent); activeCursors.put(cursorID, activeCursor); return activeCursor; }
private void deployClusterConnection(final ClusterConnectionConfiguration config) throws Exception { if (config.getName() == null) { ClusterManagerImpl.log.warn( "Must specify a unique name for each cluster connection. This one will not be deployed."); return; } if (config.getAddress() == null) { ClusterManagerImpl.log.warn( "Must specify an address for each cluster connection. This one will not be deployed."); return; } TransportConfiguration connector = configuration.getConnectorConfigurations().get(config.getConnectorName()); if (connector == null) { log.warn( "No connector with name '" + config.getConnectorName() + "'. The cluster connection will not be deployed."); return; } if (clusterConnections.containsKey(config.getName())) { log.warn( "Cluster Configuration '" + config.getConnectorName() + "' already exists. The cluster connection will not be deployed.", new Exception("trace")); return; } ClusterConnectionImpl clusterConnection; if (config.getDiscoveryGroupName() != null) { DiscoveryGroupConfiguration dg = configuration.getDiscoveryGroupConfigurations().get(config.getDiscoveryGroupName()); if (dg == null) { ClusterManagerImpl.log.warn( "No discovery group with name '" + config.getDiscoveryGroupName() + "'. The cluster connection will not be deployed."); return; } if (log.isDebugEnabled()) { log.debug( this + " Starting a Discovery Group Cluster Connection, name=" + config.getDiscoveryGroupName() + ", dg=" + dg); } clusterConnection = new ClusterConnectionImpl( this, dg, connector, new SimpleString(config.getName()), new SimpleString(config.getAddress()), config.getMinLargeMessageSize(), config.getClientFailureCheckPeriod(), config.getConnectionTTL(), config.getRetryInterval(), config.getRetryIntervalMultiplier(), config.getMaxRetryInterval(), config.getReconnectAttempts(), config.getCallTimeout(), config.getCallFailoverTimeout(), config.isDuplicateDetection(), config.isForwardWhenNoConsumers(), config.getConfirmationWindowSize(), executorFactory, server, postOffice, managementService, scheduledExecutor, config.getMaxHops(), nodeUUID, backup, server.getConfiguration().getClusterUser(), server.getConfiguration().getClusterPassword(), config.isAllowDirectConnectionsOnly()); } else { TransportConfiguration[] tcConfigs = config.getStaticConnectors() != null ? connectorNameListToArray(config.getStaticConnectors()) : null; if (log.isDebugEnabled()) { log.debug(this + " defining cluster connection towards " + Arrays.toString(tcConfigs)); } clusterConnection = new ClusterConnectionImpl( this, tcConfigs, connector, new SimpleString(config.getName()), new SimpleString(config.getAddress()), config.getMinLargeMessageSize(), config.getClientFailureCheckPeriod(), config.getConnectionTTL(), config.getRetryInterval(), config.getRetryIntervalMultiplier(), config.getMaxRetryInterval(), config.getReconnectAttempts(), config.getCallTimeout(), config.getCallFailoverTimeout(), config.isDuplicateDetection(), config.isForwardWhenNoConsumers(), config.getConfirmationWindowSize(), executorFactory, server, postOffice, managementService, scheduledExecutor, config.getMaxHops(), nodeUUID, backup, server.getConfiguration().getClusterUser(), server.getConfiguration().getClusterPassword(), config.isAllowDirectConnectionsOnly()); } if (defaultClusterConnection == null) { defaultClusterConnection = clusterConnection; } managementService.registerCluster(clusterConnection, config); clusterConnections.put(config.getName(), clusterConnection); if (log.isDebugEnabled()) { log.debug("ClusterConnection.start at " + clusterConnection, new Exception("trace")); } }
public synchronized void deployBridge(final BridgeConfiguration config, final boolean start) throws Exception { if (config.getName() == null) { ClusterManagerImpl.log.warn( "Must specify a unique name for each bridge. This one will not be deployed."); return; } if (config.getQueueName() == null) { ClusterManagerImpl.log.warn( "Must specify a queue name for each bridge. This one will not be deployed."); return; } if (config.getForwardingAddress() == null) { ClusterManagerImpl.log.debug( "Forward address is not specified. Will use original message address instead"); } if (bridges.containsKey(config.getName())) { ClusterManagerImpl.log.warn( "There is already a bridge with name " + config.getName() + " deployed. This one will not be deployed."); return; } Transformer transformer = instantiateTransformer(config.getTransformerClassName()); Binding binding = postOffice.getBinding(new SimpleString(config.getQueueName())); if (binding == null) { ClusterManagerImpl.log.warn( "No queue found with name " + config.getQueueName() + " bridge will not be deployed."); return; } Queue queue = (Queue) binding.getBindable(); ServerLocatorInternal serverLocator; if (config.getDiscoveryGroupName() != null) { DiscoveryGroupConfiguration discoveryGroupConfiguration = configuration.getDiscoveryGroupConfigurations().get(config.getDiscoveryGroupName()); if (discoveryGroupConfiguration == null) { ClusterManagerImpl.log.warn( "No discovery group configured with name '" + config.getDiscoveryGroupName() + "'. The bridge will not be deployed."); return; } if (config.isHA()) { serverLocator = (ServerLocatorInternal) HornetQClient.createServerLocatorWithHA(discoveryGroupConfiguration); } else { serverLocator = (ServerLocatorInternal) HornetQClient.createServerLocatorWithoutHA(discoveryGroupConfiguration); } } else { TransportConfiguration[] tcConfigs = connectorNameListToArray(config.getStaticConnectors()); if (tcConfigs == null) { return; } if (config.isHA()) { serverLocator = (ServerLocatorInternal) HornetQClient.createServerLocatorWithHA(tcConfigs); } else { serverLocator = (ServerLocatorInternal) HornetQClient.createServerLocatorWithoutHA(tcConfigs); } } serverLocator.setConfirmationWindowSize(config.getConfirmationWindowSize()); // We are going to manually retry on the bridge in case of failure serverLocator.setReconnectAttempts(0); serverLocator.setInitialConnectAttempts(-1); serverLocator.setRetryInterval(config.getRetryInterval()); serverLocator.setMaxRetryInterval(config.getMaxRetryInterval()); serverLocator.setRetryIntervalMultiplier(config.getRetryIntervalMultiplier()); serverLocator.setClientFailureCheckPeriod(config.getClientFailureCheckPeriod()); serverLocator.setBlockOnDurableSend(!config.isUseDuplicateDetection()); serverLocator.setBlockOnNonDurableSend(!config.isUseDuplicateDetection()); serverLocator.setMinLargeMessageSize(config.getMinLargeMessageSize()); // disable flow control serverLocator.setProducerWindowSize(-1); // This will be set to 30s unless it's changed from embedded / testing // there is no reason to exception the config for this timeout // since the Bridge is supposed to be non-blocking and fast // We may expose this if we find a good use case serverLocator.setCallTimeout(config.getCallTimeout()); if (!config.isUseDuplicateDetection()) { log.debug( "Bridge " + config.getName() + " is configured to not use duplicate detecion, it will send messages synchronously"); } clusterLocators.add(serverLocator); Bridge bridge = new BridgeImpl( serverLocator, config.getReconnectAttempts(), config.getRetryInterval(), config.getRetryIntervalMultiplier(), config.getMaxRetryInterval(), nodeUUID, new SimpleString(config.getName()), queue, executorFactory.getExecutor(), SimpleString.toSimpleString(config.getFilterString()), SimpleString.toSimpleString(config.getForwardingAddress()), scheduledExecutor, transformer, config.isUseDuplicateDetection(), config.getUser(), config.getPassword(), !backup, server.getStorageManager()); bridges.put(config.getName(), bridge); managementService.registerBridge(bridge, config); if (start) { bridge.start(); } }
public void cleanup() { ArrayList<Page> depagedPages = new ArrayList<Page>(); while (true) { if (pagingStore.lock(100)) { break; } if (!pagingStore.isStarted()) return; } synchronized (this) { try { if (!pagingStore.isStarted()) { return; } if (pagingStore.getNumberOfPages() == 0) { return; } if (log.isDebugEnabled()) { log.debug("Asserting cleanup for address " + this.pagingStore.getAddress()); } ArrayList<PageSubscription> cursorList = new ArrayList<PageSubscription>(); cursorList.addAll(activeCursors.values()); long minPage = checkMinPage(cursorList); if (minPage == pagingStore.getCurrentWritingPage() && pagingStore.getCurrentPage().getNumberOfMessages() > 0) { boolean complete = true; for (PageSubscription cursor : cursorList) { if (!cursor.isComplete(minPage)) { if (log.isDebugEnabled()) { log.debug("Cursor " + cursor + " was considered incomplete at page " + minPage); } complete = false; break; } else { if (log.isDebugEnabled()) { log.debug("Cursor " + cursor + "was considered **complete** at page " + minPage); } } } if (!pagingStore.isStarted()) { return; } if (complete) { if (log.isDebugEnabled()) { log.debug( "Address " + pagingStore.getAddress() + " is leaving page mode as all messages are consumed and acknowledged from the page store"); } pagingStore.forceAnotherPage(); Page currentPage = pagingStore.getCurrentPage(); storePositions(cursorList, currentPage); pagingStore.stopPaging(); // This has to be called after we stopped paging for (PageSubscription cursor : cursorList) { cursor.scheduleCleanupCheck(); } } } for (long i = pagingStore.getFirstPage(); i < minPage; i++) { Page page = pagingStore.depage(); if (page == null) { break; } depagedPages.add(page); } if (pagingStore.getNumberOfPages() == 0 || pagingStore.getNumberOfPages() == 1 && pagingStore.getCurrentPage().getNumberOfMessages() == 0) { pagingStore.stopPaging(); } else { if (log.isTraceEnabled()) { log.trace( "Couldn't cleanup page on address " + this.pagingStore.getAddress() + " as numberOfPages == " + pagingStore.getNumberOfPages() + " and currentPage.numberOfMessages = " + pagingStore.getCurrentPage().getNumberOfMessages()); } } } catch (Exception ex) { log.warn("Couldn't complete cleanup on paging", ex); return; } finally { pagingStore.unlock(); } } try { for (Page depagedPage : depagedPages) { PageCache cache; PagedMessage[] pgdMessages; synchronized (softCache) { cache = softCache.get((long) depagedPage.getPageId()); } if (isTrace) { log.trace("Removing page " + depagedPage.getPageId() + " from page-cache"); } if (cache == null) { // The page is not on cache any more // We need to read the page-file before deleting it // to make sure we remove any large-messages pending storageManager.beforePageRead(); List<PagedMessage> pgdMessagesList = null; try { depagedPage.open(); pgdMessagesList = depagedPage.read(storageManager); } finally { try { depagedPage.close(); } catch (Exception e) { } storageManager.afterPageRead(); } depagedPage.close(); pgdMessages = pgdMessagesList.toArray(new PagedMessage[pgdMessagesList.size()]); } else { pgdMessages = cache.getMessages(); } depagedPage.delete(pgdMessages); synchronized (softCache) { softCache.remove((long) depagedPage.getPageId()); } } } catch (Exception ex) { log.warn("Couldn't complete cleanup on paging", ex); return; } }