We're updating the issue view to help you get more done. 

Improve resilience of cleanup methods (close, etc.)

Description

We have a lot of cleanup methods that do not account for the possibility of failure.

For instance, in IndexManagerHolder.stop():

1 2 3 4 5 6 public synchronized void stop() { for ( IndexManager indexManager : getIndexManagers() ) { indexManager.destroy(); } // ... more code ... }

If the first index manager fails to stop, then none of the following index managers will be stopped. But theoretically, they could be completely different implementations, and thus the second index manager may stop perfectly well even if the first one failed.

There are many places making a similar mistake, most notably:

  • IndexManagerHolder.stop

  • Most implementations of Stoppable.stop

  • Most implementations of IndexManager.destroy

  • ImmutableSearchFactory.close

  • SearchIntegratorBuilder.cleanupFactoryState (soon to be merged as part of HSEARCH-2277)

We may want to implement "composite cleanups" in a more reliable way, for instance with a utility object similar to Guava's Closer (see here). Note this class is very simple, we don't need Guava, we can just re-implement it ourselves.

Usage examples for this "Closer":
```
public void close() throws Exception {
Closer closer = new Closer();
closer.add( entityManager ); // Specific method, entityManager does not implement Autocloseable. Maybe rather something like add( entityManager::close )?
closer.add( scrollableResults ); // Autocloseable
closer.add( statelessSession ); // Autocloseable
closer.close(); // Closes everything, uses addSuppressed if necessary, throws an Exception
}
```

try (Closer closer = new Closer()) {
// ...

EntityManager em = emf.createEntityManager();
closer.add( em );

// ...
}

Environment

None

Status

Assignee

Yoann Rodière

Reporter

Yoann Rodière

Labels

None

Suitable for new contributors

None

Feedback Requested

None

Components

Fix versions

Affects versions

5.6.1.Final
5.8.1.Final
5.7.1.Final

Priority

Major