I am trying to achieve a behavior similar to that of an event bus. For my requirements, a PublishSubject seems suitable.
The subject emits items representing a result of some global operation, which might resolve successfully or fail in case of an exception. I can't use onNext() for success events and onError() with the Throwable in case of an error, since once onError() is invoked the subject terminates and any future subscribers will get no emissions apart from an onError() one.
Right now the way I see it I have to create a class representing the event, and optionally referencing a Throwable in case of an error. This however seems unwise, as one would have to handle errors inside onNext().
How would you go about it?
Creating a generic class wrapping events is a way to go. Say we call it ResponseOrError class, it should basically contain two fields
private T data;
private Throwable error;
and two simple factory methods :
public static <T> ResponseOrError<T> fromError(Throwable throwable) {
return new ResponseOrError<>(throwable);
}
public static <T> ResponseOrError<T> fromData(T data) {
return new ResponseOrError<>(data);
}
to remove some boilerplate code you can provide Transformer to make Observable of ResponseOrError type.
public static <T> Observable.Transformer<T, ResponseOrError<T>> toResponseOrErrorObservable() {
return new Observable.Transformer<T, ResponseOrError<T>>() {
#Override
public Observable<ResponseOrError<T>> call(final Observable<T> observable) {
return observable
.map(new Func1<T, ResponseOrError<T>>() {
#Override
public ResponseOrError<T> call(final T t) {
return ResponseOrError.fromData(t);
}
})
.onErrorResumeNext(new Func1<Throwable, Observable<? extends ResponseOrError<T>>>() {
#Override
public Observable<? extends ResponseOrError<T>> call(final Throwable throwable) {
return Observable.just(ResponseOrError.<T>fromError(throwable));
}
});
}
};
}
then you can use it like that :
final Observable<ResponseOrError<ImportantData>> compose = mNetworkService
.getImportantData()
.compose(ResponseOrError.<ImportantData>toResponseOrErrorObservable());
and now you can easily map result depending on success or failure or even provide another Transformer returning mapped Observable< T> instead of Observable< ResponseOrError< T>>
Related
I'd like to have a method to send a request and then receive a response over UDP.
Here is what I've developed for the moment :
public <T extends ObjectSerializable, U extends ObjectDeserializable>
CompletableFuture<Object> execute(T request, U response)
{
var resultFuture = sender.asyncSend(request); /*CompletableFuture<Void>*/
resultFuture.thenAccept((nullObj) -> {
try {
receiver.asyncReceive(response).get(); /*CompletableFuture<Void>*/
}catch (Exception e) {
throw new FutureExecutionException(e.getMessage());
}
}).thenRun(() -> {
System.out.println("Send->Receive finished");
});
return resultFuture;
}
The question is : do I have to wait for the future inside .thenAccept ? Is it guaranteed that .thenRun will be executed after receiver.asyncReceive would finish?
Am I doing the right way combining CompletableFutures like this?
Here is a solution that looks fine
public <T extends ObjectSerializable, U extends ObjectDeserializable>
CompletableFuture<Void> execute(T request, U response)
{
return sender.asyncSend(request)
.thenCompose( result -> receiver.asyncReceive(response))
.thenRun( () -> System.out.println("Send-Receive finished"));
}
This would be a lot easier if your execute would take a Class<U> as argument. Then you could pass that class to receiver.asyncReceive. Internally, you could (assuming such a class has a default constructor) create an instance and populate it with all the fields. This is rather easy via :
clazz.getConstructor().newInstance()
Then your code would return a CompletableFuture<Response>, so your method would become something like:
public <T extends ObjectSerializable, U extends ObjectDeserializable>
CompletableFuture<U> execute(T request, Class<U> response){
return sender.asyncSend(request)
.thenCompose(nothing -> receiver.asyncReceive(response));
}
I am also not sure your asyncSend is supposed to return a CompletableFuture<Void> either, may be this one can take a Class<U> as a parameter too and return the proper type as CompletableFuture<U>, but then you do not need asyncReceive, I guess...
I'm trying to implement a simple promise system in java. I'm doing it for special purpose so please don't recommend any libraries.
I have a problem when I try to implement a thenApply() method which takes a Function as parameter, similar to what CompletableFuture has and therefore returns a promise with another type.
The promise interface:
public interface Promise<T> {
Promise<T> then(Consumer<T> handler);
<U> Promise<U> thenApply(Function<T, U> handler);
}
My implementation so far:
public class PromiseImpl<T> implements Promise<T> {
private List<Consumer<T>> resultHandlers = new ArrayList<>();
public PromiseImpl(CompletableFuture<T> future) {
future.thenAccept(this::doWork);
}
#Override
public Promise<T> then(Consumer<T> handler) {
resultHandlers.add(handler);
return this;
}
#Override
public <U> Promise<U> thenApply(Function<T, U> handler) {
// How to implement here??? I don't have the result yet
handler.apply(?);
}
private void onResult(T result) {
for (Consumer<T> handler : resultHandlers) {
handler.accept(result);
}
}
private Object doWork(T result) {
onResult(result);
return null;
}
}
The problem is that I don't know the result of my initial future in the thenApply() method, so I cannot call my handler. Also, I don't want to call future.get() because this method is blocking.
How could I make this work?
The real problem is in the design of your Promise type. It is holding a set of callbacks, all of which are to be invoked on completion. This is a fundamental problem (limiting generic functionality around the return type of thenApply's function). This can be resolved by changing your Promise implementation to return a new promise whenever a handler is registered, instead of returning this, such that each promise object will have its own handler to invoke.
In addition to solving this, it's a better design for functional-style programming, as you can make your Promise objects immutable.
I would change the interface to be:
interface Promise<T> {
<U> Promise<U> thenApply(Function<T, U> handler);
Promise<Void> thenAccept(Consumer<T> consumer);
}
The "chaining" of callbacks can then be done around the future objects to which chained Promise instances have references. So the implementation can look like:
class PromiseImpl<T> implements Promise<T> {
private CompletableFuture<T> future;
public PromiseImpl(CompletableFuture<T> future) {
this.future = future;
}
#Override
public <U> Promise<U> thenApply(Function<T, U> function) {
return new PromiseImpl<>(this.future.thenApply(function));
}
#Override
public Promise<Void> thenAccept(Consumer<T> consumer) {
return new PromiseImpl<>(this.future.thenAccept(consumer));
}
private void onResult(T result) {
this.future.complete(result);
}
private Object doWork(T result) {
onResult(result);
return null;
}
}
And using that can be as simple as:
Promise<String> stringPromise = new PromiseImpl<>(new CompletableFuture<String>());
Promise<Long> longPromise = stringPromise.thenApply(str -> Long.valueOf(str.length()));
Promise<Void> voidPromise = stringPromise.thenAccept(str -> System.out.println(str));
EDIT:
Regarding Michael's comment about retrieving the value: that was not added as it wasn't in the original Promise API. But it's easy enough to add:
T get(); //To the interface
And implemented with:
public T get() {
//try-catch
return this.future.get();
}
Note: this is starting to look more and more like a duplication of CompletableFuture, which raises the question of why do this at all. But assuming there will be additional Promise-like methods in this interface, the method would be wrapping the future API.
If you need to use the same Promise object with a list of call backs, then you have no choice but to parameterize the Promise interface with both Function concrete type parameters:
public interface Promise<T, U>
And U wouldn't be able to be a method generic parameter on then or thenApply.
If you want to keep the rest of your class the same and just implement the thenApply method, you have to make a new CompletableFuture since that's the only way you currently have to construct a new Promise:
#Override
public <U> Promise<U> thenApply(Function<T, U> handler) {
CompletableFuture<U> downstream = new CompletableFuture<>();
this.then(t -> downstream.complete(handler.apply(t)));
return new PromiseImpl<>(downstream);
}
If you can add a private no-argument constructor for PromiseImpl, you can avoid making a new CompletableFuture:
#Override
public <U> Promise<U> thenApply(Function<T, U> handler) {
PromiseImpl result = new PromiseImpl();
this.then(t -> result.doWork(handler.apply(t)));
return result;
}
But really what you should do if you want to implement your own API on top of CompletableFuture is use the decorator pattern and wrap a CompletableFuture instance as a private variable in PromiseImpl.
You can return some anonymous class that extends your PromiseImpl and overrides onResult so handlers accept the result of applying mapper function. Do not forget to call the parent onResult so parent handlers will be called.
When executing async CompletableFuture, the parent threadcontext and moreover the org.slf4j.MDC context is lost.
This is bad as I'm using some kind of "fish tagging" to track logs from one request among multiple logfiles.
MDC.put("fishid", randomId())
Question: how can I retain that id during the tasks of CompletableFutures in general?
List<CompletableFuture<UpdateHotelAllotmentsRsp>> futures =
tasks.stream()
.map(task -> CompletableFuture.supplyAsync(
() -> businesslogic(task))
.collect(Collectors.toList());
List results = futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
public void businesslogic(Task task) {
LOGGER.info("mdc fishtag context is lost here");
}
The most readable way I solved this problem was as below -
---------------Thread utils class--------------------
public static Runnable withMdc(Runnable runnable) {
Map<String, String> mdc = MDC.getCopyOfContextMap();
return () -> {
MDC.setContextMap(mdc);
runnable.run();
};
}
public static <U> Supplier<U> withMdc(Supplier<U> supplier) {
Map<String, String> mdc = MDC.getCopyOfContextMap();
return (Supplier) () -> {
MDC.setContextMap(mdc);
return supplier.get();
};
}
---------------Usage--------------
CompletableFuture.supplyAsync(withMdc(() -> someSupplier()))
.thenRunAsync(withMdc(() -> someRunnable())
....
WithMdc in ThreadUtils would have to be overloaded to include other functional interfaces which are accepted by CompletableFuture
Please note that the withMdc() method is statically imported to improve readability.
At the end I created a Supplier wrapper retaining the MDC. If anyone has a better idea feel free to comment.
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) {
return CompletableFuture.supplyAsync(new SupplierMDC(supplier), executor);
}
private static class SupplierMDC<T> implements Supplier<T> {
private final Supplier<T> delegate;
private final Map<String, String> mdc;
public SupplierMDC(Supplier<T> delegate) {
this.delegate = delegate;
this.mdc = MDC.getCopyOfContextMap();
}
#Override
public T get() {
MDC.setContextMap(mdc);
return delegate.get();
}
}
My solution theme would be to (It would work with JDK 9+ as a couple of overridable methods are exposed since that version)
Make the complete ecosystem aware of MDC
And for that, we need to address the following scenarios:
When all do we get new instances of CompletableFuture from within this class? → We need to return a MDC aware version of the same rather.
When all do we get new instances of CompletableFuture from outside this class? → We need to return a MDC aware version of the same rather.
Which executor is used when in CompletableFuture class? → In all circumstances, we need to make sure that all executors are MDC aware
For that, let's create a MDC aware version class of CompletableFuture by extending it. My version of that would look like below
import org.slf4j.MDC;
import java.util.Map;
import java.util.concurrent.*;
import java.util.function.Function;
import java.util.function.Supplier;
public class MDCAwareCompletableFuture<T> extends CompletableFuture<T> {
public static final ExecutorService MDC_AWARE_ASYNC_POOL = new MDCAwareForkJoinPool();
#Override
public CompletableFuture newIncompleteFuture() {
return new MDCAwareCompletableFuture();
}
#Override
public Executor defaultExecutor() {
return MDC_AWARE_ASYNC_POOL;
}
public static <T> CompletionStage<T> getMDCAwareCompletionStage(CompletableFuture<T> future) {
return new MDCAwareCompletableFuture<>()
.completeAsync(() -> null)
.thenCombineAsync(future, (aVoid, value) -> value);
}
public static <T> CompletionStage<T> getMDCHandledCompletionStage(CompletableFuture<T> future,
Function<Throwable, T> throwableFunction) {
Map<String, String> contextMap = MDC.getCopyOfContextMap();
return getMDCAwareCompletionStage(future)
.handle((value, throwable) -> {
setMDCContext(contextMap);
if (throwable != null) {
return throwableFunction.apply(throwable);
}
return value;
});
}
}
The MDCAwareForkJoinPool class would look like (have skipped the methods with ForkJoinTask parameters for simplicity)
public class MDCAwareForkJoinPool extends ForkJoinPool {
//Override constructors which you need
#Override
public <T> ForkJoinTask<T> submit(Callable<T> task) {
return super.submit(MDCUtility.wrapWithMdcContext(task));
}
#Override
public <T> ForkJoinTask<T> submit(Runnable task, T result) {
return super.submit(wrapWithMdcContext(task), result);
}
#Override
public ForkJoinTask<?> submit(Runnable task) {
return super.submit(wrapWithMdcContext(task));
}
#Override
public void execute(Runnable task) {
super.execute(wrapWithMdcContext(task));
}
}
The utility methods to wrap would be such as
public static <T> Callable<T> wrapWithMdcContext(Callable<T> task) {
//save the current MDC context
Map<String, String> contextMap = MDC.getCopyOfContextMap();
return () -> {
setMDCContext(contextMap);
try {
return task.call();
} finally {
// once the task is complete, clear MDC
MDC.clear();
}
};
}
public static Runnable wrapWithMdcContext(Runnable task) {
//save the current MDC context
Map<String, String> contextMap = MDC.getCopyOfContextMap();
return () -> {
setMDCContext(contextMap);
try {
return task.run();
} finally {
// once the task is complete, clear MDC
MDC.clear();
}
};
}
public static void setMDCContext(Map<String, String> contextMap) {
MDC.clear();
if (contextMap != null) {
MDC.setContextMap(contextMap);
}
}
Below are some guidelines for usage:
Use the class MDCAwareCompletableFuture rather than the class CompletableFuture.
A couple of methods in the class CompletableFuture instantiates the self version such as new CompletableFuture.... For such methods (most of the public static methods), use an alternative method to get an instance of MDCAwareCompletableFuture. An example of using an alternative could be rather than using CompletableFuture.supplyAsync(...), you can choose new MDCAwareCompletableFuture<>().completeAsync(...)
Convert the instance of CompletableFuture to MDCAwareCompletableFuture by using the method getMDCAwareCompletionStage when you get stuck with one because of say some external library which returns you an instance of CompletableFuture. Obviously, you can't retain the context within that library but this method would still retain the context after your code hits the application code.
While supplying an executor as a parameter, make sure that it is MDC Aware such as MDCAwareForkJoinPool. You could create MDCAwareThreadPoolExecutor by overriding execute method as well to serve your use case. You get the idea!
With that, your code would look like
List<CompletableFuture<UpdateHotelAllotmentsRsp>> futures =
tasks.stream()
new MDCAwareCompletableFuture<UpdateHotelAllotmentsRsp>().completeAsync(
() -> businesslogic(task))
.collect(Collectors.toList());
List results = futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
public UpdateHotelAllotmentsRsp businesslogic(Task task) {
LOGGER.info("mdc fishtag context is not lost here");
}
You can find a detailed explanation of all of the above here in a post about the same.
YES, Twitter Future did this correctly. They have a class Local.scala that Future.scala knows about.
The fix is for java authors to fix this issue so your Local state travels through ALL libaries that use CompletableFutures. Basically, Local.scala is used by Future and internally uses a ThreadLocal up until .thenApply or .thenAccept and it will capture state and transfer it when needed to the next one on and on. This works through all third party libraries with ZERO 3rd party library changes.
Here is more but poke Java Authors to fix their stuff...
http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-May/047867.html
until then, MDC will NEVER work through 3rd party libraries.
My SO post on this
Does CompletableFuture have a corresponding Local context?
I'm trying to create a simple way to fire CRUD-type events for different domain classes. I've created the following event class:
public class EntityModifiedEvent<E> extends Event<EntityModifiedEventHandler<E>> {
private E element;
private ModType modType;
private Class<E> clazz;
private static Map<String,GwtEvent.Type<EntityModifiedEventHandler<?>>> types = new HashMap<String, GwtEvent.Type<EntityModifiedEventHandler<?>>>();
public EntityModifiedEvent(ModType modType, E element, Class<E> clazz) {
this.element = element;
this.modType = modType;
this.clazz = clazz;
}
public Type<EntityModifiedEventHandler<?>> getType() {
return getType(clazz);
}
#SuppressWarnings({"rawtypes", "unchecked"})
public static GwtEvent.Type<EntityModifiedEventHandler<?>> getType(Class clazz) {
GwtEvent.Type type = types.get(clazz.toString());
if (type == null) {
type = new GwtEvent.Type<EntityModifiedEventHandler<?>>();
types.put(clazz.toString(), type);
}
return type;
}
public E getElement(){
return element;
}
public ModType getModType() {
return modType;
}
#SuppressWarnings({"unchecked", "rawtypes"})
#Override
public Type<EntityModifiedEventHandler<E>> getAssociatedType() {
return (Type) getType();
}
#Override
protected void dispatch(EntityModifiedEventHandler<E> handler) {
handler.onEntityModified(this);
};
public interface EntityModifiedEventHandler<E> extends EventHandler {
void onEntityModified(EntityModifiedEvent<E> entityModifiedEvent);
}
So, any class can register itself as a listener as follow:
getEventBus().addHandler(EntityModifiedEvent.getType(MyDomainClass.class), this);
And the events will be fired like:
getEventBus().fireEventFromSource(new EntityModifiedEvent<MyDomainClass>(ModType.CREATE, instanceModified, MyDomainClass.class), this);
ModType is just a simple Enum with the different types of modifications.
I have some concerns about having a map with all class.toString->eventTypes in this class itself. Do you think this will bring performance issues?
Also, this approach relies on the EventBus using Type object's hashcode to identify the handlers registered for that type (see getType(Class clazz) function). Do you think it's wrong to rely on it?
Any other suggestion about how to do this? Any comment will be much appreciated!
You have to ask yourself what do you gain from such an approach?
Performance - no. I don't have solid numbers on this (I'd have to be able to profile your application), but it's seems that this offers no measurable performance gains, if any. The number of fired events will be the same, but the number of receivers will be greater than with a more fine-grained approach. Plus, there's the type checking.
The ability to perform some common code when any entity modified event is fired, regardless of its type. This is true, but read on on how to achieve it with specific events.
Using specific events for the exact operation that was performed seems like a better choice:
It makes it clear who listens to what event.
The events can have extra metadata specific to the event (how many records where deleted, do you need to flush the cache, etc.)
I'd recommend looking at gwteventbinder to trim some of the boilerplate and improve your code. It also allows for handling several events in one method:
class SuperEvent extends GenericEvent { }
class EventOne extends SuperEvent { }
class EventTwo extends SuperEvent { }
class FormPresenter {
interface MyEventBinder extends EventBinder<FormPresenter> {}
private final MyEventBinder eventBinder = GWT.create(MyEventBinder.class);
FormPresenter(EventBus eventBus) {
eventBinder.bindEventHandlers(this, eventBus);
}
#EventHandler
void onEventOne(EventOne event) {
// handler for EventOne
}
#EventHandler(handles = {EventOne.class, EventTwo.class})
void onEventOneAndTwo(SuperEvent event) {
// handler for EventOne and EventTwo
}
#EventHandler(handles = {EventOne.class, EventTwo.class})
void onEventOneAndTwo2() {
// handler for EventOne and EventTwo without parameter
}
}
I have a utility class that extends Async task. I will be using this call to make HTTP requests in the background but I will also have more specialized sub classes of this that prepare the parameters, headers, url to call, so I can remove more common work from the GUI.
The issue is that I want to make use of Generics. The base API class doInBackground will return a string, there's a more specialized Json subclass that will call parent and return a JSONObject and do some parsing of the json response, there's specialized classes that extend the Json subclass and return List of custom objects, and so on. The reason for this is if we need to swap in XML and XML processing the specialized sub classes will have both a JSON and XML implementation. This is because we are re-using for a couple different api's overall.
So I tried playing around with Generics but I'm not 100% sure I understand the implementation in this case. It's obvious when you want to do things like List and make a list of List but how do I apply it here? I think I'm mainly confused about mocking up the code vs implementation, will everything just be T in the base and subclasses, than when I instantiate instances somewhere else like in the GUI that's when I specify the type of return I expect? Than I think I understand. So what I'm saying is when writing up the classes I only use T, never specify a Type and in the code where I instantiate instances that's when I specify a type and that's what the return type of doInBackground will be?
I also want to be able to implement onPostExecute() generically because I will use a callback setup so the GUI can easily subscribe to when the call is finished and process the result, but the interfact will also have a generic for the onPostExecute(T response). So I can create new instances, pass 'this', and when the async task is finished it will call the callback with the result and the callback can handle the appropriate type.
public class Base<T> extends AsyncTask<String, Integer, T>
{
protected Callback callback = null; //interface implemented for processing response
public Base setCallback(Callback callback){ this.callback = callback; return this; }
#Override
protected T doInBackground(String... uri)
{
//do http call
String response = "";
return response; //raw string of server response
}
#Override
final protected void onPostExecute(T result)
{
//no overrides, same every time
if( callback != null )
{
callback.finished(result); //forward generic result, but there it will be typed
}
}
public class JsonBase<T> extends Base<T>
{
#Override
protected T doInBackground(String... uri)
{
//this will be a JSONObject returned
String result = (String)super.dpInBackground(uri); //gives me back a string
return new JSONObject(result); //return a json object
}
}
public class SpecializedBase<T> extends JsonBase<T>
{
#Override
protected T doInBackground(String... uri)
{
//this will be a List<String> returned
//iterate over all json array strings and pass back
return new List<String>();
}
}
class FragmentFoo extends Fragment implements Callback
{
#Override
protected void onViewCreate(...)
{
//Example usage
new JsonBase< JSONObject >().setCallback(this).execute("<url">);
new SpecializedBase< List<String> >().setCallback(this).execute(""); //hard coded internally for example
}
//Can we do something like this?
#Override
protected void finished(JSONObject object)
{
//handle json response
}
#Override
protected void finished(List<String> strings)
{
//handle list of strings response
}
}
interface Callback
{
public <T> void finish(T response);
}
The specialized sub classes of Async will be tailored to specific types, and return different types, and we want to handle those specialized type depending on where we are in the GUI and what we're doing. Otherwise all we can do is all the logic in the GUI or have another middle layer of wrappers...This is all just a primitive example illustrating my point and how we want this to work.
Just kept T and anytime it complained about casting (T)response I just added a suppress warning. As long as I know what to expect in the specific callback and cast to that type, it's fine. But could easily crash at runtime if I make a mistake and cast it to something else.
It compiles, runs, and works. But doesn't seem like a clean appropriate solution.
I know this is an old question but I've just come across it - used most of your solution and improved it a little to solve the issue you had.
I'll just paste the code, but basically just type the list but rather than using it as a return value I use an integer static for the return value in the callback and create the list as a field of the asynctask object itself which is then accessed in the callback method. (I also use a DatabaseLoaderParams for clarity)
public class DatabaseLoader<T> extends AsyncTask<DatabaseLoaderParams, Void, Integer> {
ArrayList<T> returnList;
protected DbLoaderCallback callback = null; //interface implemented for processing response
public DatabaseLoader setCallback(DbLoaderCallback callback){ this.callback = callback; return this; }
#Override
protected Integer doInBackground(DatabaseLoaderParams... params) {
//you have to give the object class to the asynctask
ArrayList<T> mReturnList = getList(params[0].objectClass);
try {
// DB loading code
} catch (Exception e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
return 0;
}
// Done!
returnList=mReturnList;
return params[0].startId;
}
#Override
final protected void onPostExecute(Integer startId)
{
if( callback != null && startId>0)
{
callback.onLoadFinished(startId); //forward generic result, but there it will be typed
}
}
private <T> ArrayList<T> getList(Class<T> requiredType) {
return new ArrayList<T>();
}
In the activity:
#Override
public void onLoadFinished(int startId)
{
switch(startId){
case INTEGER_STATIC:
//check the type if you want but I don't bother
for(DBObject dbObject : DBLoader.returnList){
....