zeroc-ice / ice

All-in-one solution for creating networked applications with RPC, pub/sub, server deployment, and more.
https://zeroc.com
GNU General Public License v2.0
2k stars 592 forks source link

Review handling of OutOfMemoryError in Java #2276

Closed pepone closed 2 weeks ago

pepone commented 3 weeks ago

The Ice for Java runtime as of 3.7 traps OutOfMemoryError or AssertionError thrown by servants, and logs it. See Raising Exceptions in Java

This behavior is not configurable; some applications would prefer to deal with this using a different strategy, for example, letting the application crash.

For 3.8 we can move this behavior to an [UncaughtExceptionHandler] for the server thread pool threads, and allow the users to provide their own UncaughtExceptionHandler when creating an adapter or with InitiliazationData.

See also Discussion 2225

bernardnormier commented 2 weeks ago

This special behavior is only about synchronous exceptions that bubble up in the dispatch.

With a "CompletionStage" dispatch, where the returned completion stage is completed by an error (by the dispatch thread or some other thread), there is not much we can do. Just kill the current thread when we get an Error? Abort the JVM? This doesn't seem realistic.

See also #2291.

bernardnormier commented 2 weeks ago

I propose that we supply an ErrorHandlerMiddleware that the user can install. This middleware will just callback the user-supplied Consumer. Something like:

public final class ErrorHandlerMiddleware implements Object {
    public ErrorHandlerMiddleware(Object next, Consumer<Error>) { ... }

}

public final class ObjectAdapter {
    public ObjectAdapter useErrorHandler(Consumer<Error> errorHandler) { ... }
}

The ErrorHandlerMiddleware gives the error to the handler, which can print a message to the Console, send a Slack message, abort the application (...). If the handler does nothing, the ErrorHandlerMiddleware does nothing.

Then, regardless of the installation of this error handler middleware, all errors are treated like miscellaneous exceptions: logged as error (by the internal Logger middleware) and marshaled as UnknownException. They never kill the dispatch thread.