Skip to content

Commit

Permalink
HSEARCH-2979 Integrate with ExtendedBeanManager.LifecycleListener#bef…
Browse files Browse the repository at this point in the history
…oreBeanManagerDestroyed

We cannot easily test this for now, because WildFly does not implement
this event yet.
  • Loading branch information
yrodiere committed Feb 7, 2018
1 parent fcba366 commit d44f92e
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 5 deletions.
Expand Up @@ -20,18 +20,25 @@ class ExtendedBeanManagerSynchronizer

private final CompletableFuture<Void> environmentInitialized = new CompletableFuture<>();

private final CompletableFuture<Void> environmentDestroying = new CompletableFuture<>();

@Override
public void whenEnvironmentReady(Runnable runnable) {
environmentInitialized.thenRun( runnable );
}

@Override
public void whenEnvironmentDestroying(Runnable runnable) {
environmentDestroying.thenRun( runnable );
}

@Override
public void beanManagerInitialized(BeanManager beanManager) {
environmentInitialized.complete( null );
}

@Override
public void beforeBeanManagerDestroyed(BeanManager beanManager) {
// No-op
environmentDestroying.complete( null );
}
}
Expand Up @@ -23,6 +23,7 @@
import org.hibernate.search.hcore.spi.EnvironmentSynchronizer;
import org.hibernate.search.spi.SearchIntegrator;
import org.hibernate.search.spi.SearchIntegratorBuilder;
import org.hibernate.search.util.impl.Closer;

/**
* A {@code SessionFactoryObserver} registered with Hibernate ORM during the integration phase. This observer will
Expand All @@ -45,6 +46,7 @@ public class HibernateSearchSessionFactoryObserver implements SessionFactoryObse
private final Metadata metadata;

private final CompletableFuture<ExtendedSearchIntegrator> extendedSearchIntegratorFuture = new CompletableFuture<>();
private final CompletableFuture<?> extendedSearchIntegratorClosingTrigger = new CompletableFuture<>();

//Guarded by synchronization on this
private JMXHook jmx;
Expand All @@ -64,6 +66,15 @@ public HibernateSearchSessionFactoryObserver(
this.environmentSynchronizer = environmentSynchronizer;
this.managedBeanRegistry = managedBeanRegistry;
this.namingService = namingService;

/*
* Make sure that if a Search integrator is created, it will eventually get closed,
* either when the environment is destroyed (see the use of EnvironmentSynchronizer in #sessionFactoryCreated)
* or when the session factory is closed (see #sessionFactoryClosed),
* whichever happens first.
*/
extendedSearchIntegratorFuture.thenAcceptBoth( extendedSearchIntegratorClosingTrigger,
(integrator, ignored) -> this.cleanup( integrator ) );
}

@Override
Expand All @@ -73,6 +84,10 @@ public void sessionFactoryCreated(SessionFactory factory) {
listener.initialize( extendedSearchIntegratorFuture );

if ( environmentSynchronizer != null ) {
environmentSynchronizer.whenEnvironmentDestroying( () -> {
// Trigger integrator closing if the integrator actually exists and wasn't already closed
extendedSearchIntegratorClosingTrigger.complete( null );
} );
environmentSynchronizer.whenEnvironmentReady( () -> {
try {
boot( factory );
Expand Down Expand Up @@ -154,14 +169,24 @@ private synchronized void cancelBoot() {

@Override
public void sessionFactoryClosed(SessionFactory factory) {
extendedSearchIntegratorFuture.thenAccept( this::cleanup );
/*
* Trigger integrator closing if the integrator actually exists and wasn't already closed
* The closing might have been triggered already if an EnvironmentSynchronizer is being used
* (see #sessionFactoryCreated).
*/
extendedSearchIntegratorClosingTrigger.complete( null );
}

private synchronized void cleanup(ExtendedSearchIntegrator extendedIntegrator) {
if ( extendedIntegrator != null ) {
extendedIntegrator.close();
try (Closer<RuntimeException> closer = new Closer<>()) {
if ( extendedIntegrator != null ) {
closer.push( extendedIntegrator::close );
}
if ( jmx != null ) {
closer.push( jmx::unRegisterIfRegistered );
jmx = null;
}
}
jmx.unRegisterIfRegistered();
}

}
Expand Down
Expand Up @@ -32,4 +32,16 @@ public interface EnvironmentSynchronizer extends Service {
*/
void whenEnvironmentReady(Runnable runnable);

/**
* Run the given work just before the environment is
* destroyed (exactly what "destroyed" means is
* implementation-dependent).
* <p>
* If the environment is already "destroyed", run the
* work now, synchronously.
*
* @param runnable
*/
void whenEnvironmentDestroying(Runnable runnable);

}

0 comments on commit d44f92e

Please sign in to comment.