ice icon indicating copy to clipboard operation
ice copied to clipboard

Simplify DispatchInterceptor API

Open bernardnormier opened this issue 6 years ago • 0 comments

Dispatch interceptors are currently a separate servant abstract class: the application-code derives from DispatchInterceptor, implements dispatch, and calls ice_dispatch on the real servant. And under the hood, the "real" dispatch function, _iceDispatch, calls dispatch for the dispatch interceptor servant. For real servants, ice_dispatch calls _iceDispatch. For example in Java:

default CompletionStage<OutputStream> ice_dispatch(Request request)
        throws UserException
    {
        Incoming in = (Incoming)request;
        in.startOver();
        return _iceDispatch(in, in.getCurrent());
    }

I propose to simplify all this by using a single dispatch method, ice_dispatch:

    CompletionStage<OutputStream> ice_dispatch(Incoming request, Current current)

where the request parameter is a completely opaque type for the application, and current is provided as a separate parameter. This signature is more consistent with the method dispatch implemented by the application: these methods have a trailing Current parameter.

ice_dispatch would replace the existing dispatch/_iceDispatch/ice_dispatch, and a Dispatch interceptor would no longer be a separate class: any servant class that overrides ice_dispatch would be a dispatch interceptor. In particular, in C++ and Java, the application could override ice_dispatch in its servant class, and by doing so intercept dispatches. (With Ice 3.7, overriding ice_dispatch does not do anything, since Ice calls _iceDispatch, and ice_dispatch is just a wrapper that calls _iceDispatch).

Ice for Swift already uses this "single public dispatch method" model.

The retry support (in.startOver() in the Java snippet above) would move to the implementation of ice_dispatch in the generated code and a few built-in servants like Blobject and BlobjectAsync.

bernardnormier avatar Jun 14 '19 22:06 bernardnormier