Search in sources :

Example 11 with Group

use of org.wildfly.clustering.group.Group in project quickstart by wildfly.

the class ServiceActivator method activate.

@Override
public void activate(ServiceActivatorContext serviceActivatorContext) {
    try {
        SingletonPolicy policy = (SingletonPolicy) serviceActivatorContext.getServiceRegistry().getRequiredService(ServiceName.parse(SingletonDefaultRequirement.SINGLETON_POLICY.getName())).awaitValue();
        InjectedValue<Group> group = new InjectedValue<>();
        Service<Node> primary = new SingletonService(true, group);
        Service<Node> backup = new SingletonService(false, group);
        policy.createSingletonServiceBuilder(SINGLETON_SERVICE_NAME, primary, backup).build(serviceActivatorContext.getServiceTarget()).addDependency(ServiceName.parse("org.wildfly.clustering.default-group"), Group.class, group).install();
        LOG.info("Singleton service activated.");
    } catch (InterruptedException e) {
        throw new ServiceRegistryException(e);
    }
}
Also used : Group(org.wildfly.clustering.group.Group) InjectedValue(org.jboss.msc.value.InjectedValue) SingletonPolicy(org.wildfly.clustering.singleton.SingletonPolicy) Node(org.wildfly.clustering.group.Node) ServiceRegistryException(org.jboss.msc.service.ServiceRegistryException)

Example 12 with Group

use of org.wildfly.clustering.group.Group in project wildfly by wildfly.

the class AbstractDistributedSingletonService method providersChanged.

@Override
public synchronized void providersChanged(Set<Node> nodes) {
    Group group = this.registry.get().getGroup();
    List<Node> candidates = new ArrayList<>(group.getMembership().getMembers());
    candidates.retainAll(nodes);
    // Only run election on a single node
    if (candidates.isEmpty() || candidates.get(0).equals(group.getLocalMember())) {
        // First validate that quorum was met
        int size = candidates.size();
        boolean quorumMet = size >= this.quorum;
        if ((this.quorum > 1) && (size == this.quorum)) {
            // Log fragility of singleton availability
            ClusteringServerLogger.ROOT_LOGGER.quorumJustReached(this.name.getCanonicalName(), this.quorum);
        }
        Node elected = quorumMet ? this.electionPolicy.elect(candidates) : null;
        try {
            if (elected != null) {
                // Stop service on every node except elected node
                for (Map.Entry<Node, CompletionStage<Void>> entry : this.dispatcher.executeOnGroup(new StopCommand(), elected).entrySet()) {
                    try {
                        entry.getValue().toCompletableFuture().join();
                    } catch (CancellationException e) {
                        ClusteringServerLogger.ROOT_LOGGER.tracef("Singleton service %s is not installed on %s", this.name.getCanonicalName(), entry.getKey().getName());
                    } catch (CompletionException e) {
                        Throwable cause = e.getCause();
                        if ((cause instanceof IllegalStateException) && (cause.getCause() instanceof ServiceNotFoundException)) {
                            ClusteringServerLogger.ROOT_LOGGER.debugf("Singleton service %s is no longer installed on %s", this.name.getCanonicalName(), entry.getKey().getName());
                        } else {
                            throw e;
                        }
                    }
                }
                // Start service on elected node
                try {
                    this.dispatcher.executeOnMember(new StartCommand(), elected).toCompletableFuture().join();
                } catch (CancellationException e) {
                    ClusteringServerLogger.ROOT_LOGGER.debugf("Singleton service %s could not be started on the elected primary singleton provider (%s) because it left the cluster.  A new primary provider election will take place.", this.name.getCanonicalName(), elected.getName());
                } catch (CompletionException e) {
                    Throwable cause = e.getCause();
                    if ((cause instanceof IllegalStateException) && (cause.getCause() instanceof ServiceNotFoundException)) {
                        ClusteringServerLogger.ROOT_LOGGER.debugf("Service % is no longer installed on the elected primary singleton provider (%s). A new primary provider election will take place.", this.name.getCanonicalName(), elected.getName());
                    } else {
                        throw e;
                    }
                }
            } else {
                if (!quorumMet) {
                    ClusteringServerLogger.ROOT_LOGGER.quorumNotReached(this.name.getCanonicalName(), this.quorum);
                }
                // Stop service on every node
                for (Map.Entry<Node, CompletionStage<Void>> entry : this.dispatcher.executeOnGroup(new StopCommand()).entrySet()) {
                    try {
                        entry.getValue().toCompletableFuture().join();
                    } catch (CancellationException e) {
                        ClusteringServerLogger.ROOT_LOGGER.tracef("Singleton service %s is not installed on %s", this.name.getCanonicalName(), entry.getKey().getName());
                    } catch (CompletionException e) {
                        Throwable cause = e.getCause();
                        if ((cause instanceof IllegalStateException) && (cause.getCause() instanceof ServiceNotFoundException)) {
                            ClusteringServerLogger.ROOT_LOGGER.debugf("Singleton service %s is no longer installed on %s", this.name.getCanonicalName(), entry.getKey().getName());
                        } else {
                            throw e;
                        }
                    }
                }
            }
            if (this.electionListener != null) {
                for (CompletionStage<Void> stage : this.dispatcher.executeOnGroup(new SingletonElectionCommand(candidates, elected)).values()) {
                    try {
                        stage.toCompletableFuture().join();
                    } catch (CancellationException e) {
                    // Ignore
                    }
                }
            }
        } catch (CommandDispatcherException e) {
            throw new IllegalStateException(e);
        }
    }
}
Also used : Group(org.wildfly.clustering.group.Group) CommandDispatcherException(org.wildfly.clustering.dispatcher.CommandDispatcherException) Node(org.wildfly.clustering.group.Node) ArrayList(java.util.ArrayList) CancellationException(java.util.concurrent.CancellationException) ServiceNotFoundException(org.jboss.msc.service.ServiceNotFoundException) CompletionException(java.util.concurrent.CompletionException) Map(java.util.Map) CompletionStage(java.util.concurrent.CompletionStage)

Example 13 with Group

use of org.wildfly.clustering.group.Group in project wildfly by wildfly.

the class BeanExpirationSchedulerTestCase method testImmortal.

@Test
public void testImmortal() throws InterruptedException {
    Group group = mock(Group.class);
    Batcher<TransactionBatch> batcher = mock(Batcher.class);
    BeanFactory<String, Object> factory = mock(BeanFactory.class);
    ExpirationConfiguration<Object> config = mock(ExpirationConfiguration.class);
    RemoveListener<Object> listener = mock(RemoveListener.class);
    BeanEntry<String> entry = mock(BeanEntry.class);
    BeanRemover<String, Object> remover = mock(BeanRemover.class);
    String beanId = "immortal";
    when(group.isSingleton()).thenReturn(true);
    // Fun fact: the Jakarta Enterprise Beans specification allows a timeout value of 0, so only negative timeouts are treated as immortal
    when(config.getTimeout()).thenReturn(Duration.ofMinutes(-1L));
    when(config.getRemoveListener()).thenReturn(listener);
    when(entry.getLastAccessedTime()).thenReturn(Instant.now());
    try (Scheduler<String, ImmutableBeanEntry<String>> scheduler = new BeanExpirationScheduler<>(group, batcher, factory, config, remover, Duration.ZERO)) {
        scheduler.schedule(beanId, entry);
        Thread.sleep(500);
    }
    verify(batcher, never()).createBatch();
    verify(remover, never()).remove(beanId, listener);
}
Also used : Group(org.wildfly.clustering.group.Group) TransactionBatch(org.wildfly.clustering.ee.cache.tx.TransactionBatch) Test(org.junit.Test)

Example 14 with Group

use of org.wildfly.clustering.group.Group in project wildfly by wildfly.

the class BeanExpirationSchedulerTestCase method testNotYetExpired.

@Test
public void testNotYetExpired() throws InterruptedException {
    Group group = mock(Group.class);
    Batcher<TransactionBatch> batcher = mock(Batcher.class);
    TransactionBatch batch = mock(TransactionBatch.class);
    BeanFactory<String, Object> factory = mock(BeanFactory.class);
    ExpirationConfiguration<Object> config = mock(ExpirationConfiguration.class);
    RemoveListener<Object> listener = mock(RemoveListener.class);
    BeanEntry<String> entry = mock(BeanEntry.class);
    BeanRemover<String, Object> remover = mock(BeanRemover.class);
    String beanId = "not-expired";
    Duration timeout = Duration.ofMillis(10L);
    when(batcher.createBatch()).thenReturn(batch);
    when(config.getTimeout()).thenReturn(Duration.ofMillis(1L));
    when(config.getRemoveListener()).thenReturn(listener);
    when(entry.getLastAccessedTime()).thenReturn(Instant.now().plus(Duration.ofMinutes(1)));
    when(factory.findValue(beanId)).thenReturn(entry);
    when(entry.isExpired(same(timeout))).thenReturn(false);
    try (Scheduler<String, ImmutableBeanEntry<String>> scheduler = new BeanExpirationScheduler<>(group, batcher, factory, config, remover, Duration.ZERO)) {
        scheduler.schedule(beanId, entry);
        Thread.sleep(500);
    }
    verify(remover, never()).remove(beanId, listener);
    verify(batch, never()).close();
}
Also used : Group(org.wildfly.clustering.group.Group) TransactionBatch(org.wildfly.clustering.ee.cache.tx.TransactionBatch) Duration(java.time.Duration) Test(org.junit.Test)

Example 15 with Group

use of org.wildfly.clustering.group.Group in project wildfly by wildfly.

the class BeanExpirationSchedulerTestCase method testCancel.

@Test
public void testCancel() throws InterruptedException {
    Group group = mock(Group.class);
    Batcher<TransactionBatch> batcher = mock(Batcher.class);
    BeanFactory<String, Object> factory = mock(BeanFactory.class);
    ExpirationConfiguration<Object> config = mock(ExpirationConfiguration.class);
    RemoveListener<Object> listener = mock(RemoveListener.class);
    BeanEntry<String> entry = mock(BeanEntry.class);
    BeanRemover<String, Object> remover = mock(BeanRemover.class);
    String beanId = "canceled";
    Duration timeout = Duration.ofMinutes(1L);
    when(config.getTimeout()).thenReturn(timeout);
    when(config.getRemoveListener()).thenReturn(listener);
    when(entry.getLastAccessedTime()).thenReturn(Instant.now());
    try (Scheduler<String, ImmutableBeanEntry<String>> scheduler = new BeanExpirationScheduler<>(group, batcher, factory, config, remover, Duration.ZERO)) {
        scheduler.schedule(beanId, entry);
        Thread.sleep(500);
        scheduler.cancel(beanId);
    }
    verify(remover, never()).remove(beanId, listener);
    verify(batcher, never()).createBatch();
}
Also used : Group(org.wildfly.clustering.group.Group) TransactionBatch(org.wildfly.clustering.ee.cache.tx.TransactionBatch) Duration(java.time.Duration) Test(org.junit.Test)

Aggregations

Group (org.wildfly.clustering.group.Group)19 Test (org.junit.Test)7 InjectedValue (org.jboss.msc.value.InjectedValue)6 Node (org.wildfly.clustering.group.Node)6 TransactionBatch (org.wildfly.clustering.ee.cache.tx.TransactionBatch)4 Duration (java.time.Duration)3 Service (org.jboss.msc.Service)3 ServiceRegistryException (org.jboss.msc.service.ServiceRegistryException)3 FunctionalService (org.wildfly.clustering.service.FunctionalService)3 SingletonPolicy (org.wildfly.clustering.singleton.SingletonPolicy)3 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 CommandDispatcherException (org.wildfly.clustering.dispatcher.CommandDispatcherException)2 NamePreference (org.wildfly.clustering.singleton.election.NamePreference)2 PreferredSingletonElectionPolicy (org.wildfly.clustering.singleton.election.PreferredSingletonElectionPolicy)2 SimpleSingletonElectionPolicy (org.wildfly.clustering.singleton.election.SimpleSingletonElectionPolicy)2 RouteLocator (org.wildfly.clustering.web.routing.RouteLocator)2 AbstractMap (java.util.AbstractMap)1 SimpleImmutableEntry (java.util.AbstractMap.SimpleImmutableEntry)1 LinkedList (java.util.LinkedList)1