Skip to content

Commit

Permalink
Improve conversion of Mutiny handlers
Browse files Browse the repository at this point in the history
This is port of vert-x3/vertx-rx#324

It fixes Vert.x Web router (and others) that is broken with Mutiny API.
See vert-x3/vertx-rx#314

The purpose of this change is to avoid decorating handlers if they are instances of a generated Mutiny type (e.g. io.vertx.mutiny.ext.web.handler.StaticHandler).

Signed-off-by: Thomas Segismont <[email protected]>
  • Loading branch information
tsegismont committed Jan 9, 2025
1 parent ae0da60 commit b2a316c
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.smallrye.mutiny.vertx;

/**
* Interface implemented by every generated Mutiny type.
*/
public interface MutinyDelegate {

/**
* @return the delegate used by this Mutiny object of generated type
*/
Object getDelegate();

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

import java.util.concurrent.Executor;
import java.util.concurrent.Flow.Subscriber;
import java.util.function.Consumer;
import java.util.function.Function;

import io.smallrye.mutiny.vertx.impl.WriteStreamSubscriberImpl;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.WorkerExecutor;
import io.vertx.core.streams.WriteStream;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class MutinyHelper {

/**
Expand Down Expand Up @@ -94,6 +97,27 @@ public static Class unwrap(Class<?> type) {
return type;
}

/**
* Convert a handler for a generated Mutiny type to a handler for the corresponding core type.
*/
public static <BARE, MUTINY> Handler<BARE> convertHandler(Handler<MUTINY> mutinyHandler, Function<BARE, MUTINY> mapper) {
if (mutinyHandler instanceof MutinyDelegate) {
MutinyDelegate mutinyDelegate = (MutinyDelegate) mutinyHandler;
return (Handler<BARE>) mutinyDelegate.getDelegate();
}
return new DelegatingHandler<>(mutinyHandler, mapper);
}

/**
* Convert a consumer for a generated Mutiny type to a handler of the same type.
*/
public static <T> Handler<T> convertConsumer(Consumer<T> mutinyConsumer) {
if (mutinyConsumer instanceof MutinyDelegate) {
return (Handler<T>) mutinyConsumer;
}
return mutinyConsumer != null ? new DelegatingConsumerHandler<>(mutinyConsumer) : null;
}

/**
* Adapts a Vert.x {@link WriteStream} to a Mutiny {@link Subscriber}.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public void generate(ClassModel model, PrintWriter writer) {
}

List<String> interfaces = new ArrayList<>();
interfaces.add("io.smallrye.mutiny.vertx.MutinyDelegate");
if ("io.vertx.core.buffer.Buffer".equals(type.getName())) {
interfaces.add("io.vertx.core.shareddata.impl.ClusterSerializable");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,15 @@ public static String genConvParam(Map<MethodInfo, Map<TypeInfo, String>> methodT
ClassKind eventKind = eventType.getKind();
if (eventKind == ASYNC_RESULT) {
TypeInfo resultType = ((ParameterizedTypeInfo) eventType).getArg(0);
return "new io.smallrye.mutiny.vertx.DelegatingHandler<>(" + expr + ", ar -> ar.map(event -> " + genConvReturn(methodTypeArgMap, resultType, method, "event") + "))";
return "io.smallrye.mutiny.vertx.MutinyHelper.convertHandler(" + expr + ", ar -> ar.map(event -> " + genConvReturn(methodTypeArgMap, resultType, method, "event") + "))";
} else if (eventType.isParameterized() && eventType.getRaw().getName().equals(Promise.class.getName())) {
return "new Handler<" + genTypeName(eventType) + ">() {\n" +
" public void handle(" + genTypeName(eventType) + " event) {\n" +
" " + expr + ".subscribe().with(it -> event.complete(it), failure -> event.fail(failure));\n" +
" }\n" +
" }";
} else {
return "new io.smallrye.mutiny.vertx.DelegatingHandler<>(" + expr + ", event -> " + genConvReturn(methodTypeArgMap, eventType, method, "event") + ")";
return "io.smallrye.mutiny.vertx.MutinyHelper.convertHandler(" + expr + ", event -> " + genConvReturn(methodTypeArgMap, eventType, method, "event") + ")";
}
} else if (kind == FUNCTION) {
TypeInfo argType = parameterizedTypeInfo.getArg(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
public class GetDelegateMethodCodeWriter implements ConditionalCodeWriter {
@Override
public void generate(ClassModel model, PrintWriter writer) {
writer.println(" @Override");
writer.print(" public ");
writer.print(model.getType().getName());
writer.println(" getDelegate() {");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ private void generateBody(MutinyMethodDescriptor descriptor) {
} else if(param.getType().getName().equals(Runnable.class.getName())) {
writer.println("ignored -> " + param.getName() + ".run()");
} else {
writer.print(param.getName() + " != null ? new io.smallrye.mutiny.vertx.DelegatingConsumerHandler(" + param.getName() + ") : null");
writer.print("io.smallrye.mutiny.vertx.MutinyHelper.convertConsumer(" + param.getName() + ")");
}
}
}
Expand Down

0 comments on commit b2a316c

Please sign in to comment.