lundi 2 janvier 2017

Retry once using functional interface

I'm new to functional programming (and Java) and I want to create something nice using it, but cannot figure out how.

I'm using BiConsumer (java.util.function.BiConsumer) for calls to the server.

I'm trying to write a code which send some request to server with existing data (calling Public createSomeTask()), only if it fails, the connector will perform a retry only once.

The code is async, Private createSomeTask() calls updateTaskStage() as well.

The problem is that I have many calls in the connector (many createSomeTask()) with current implementation, the code not looks good and I'm sure there is a way to do it better using Functional interfaces or extending the BiConsumer or any other nice way in Java 8 lile , reflection, method invoke etc.

See the code below. I hope someone can help me with that.

//Main
public class Main {
    public static void main(String[] args) throws InterruptedException {
        Connector connector = new Connector();
        connector.createSomeTask("started",(response, error)->{
        });
    }
}

//Connector Class
import java.util.function.BiConsumer;

public class Connector {
    static String taskStage = null;

    public void createSomeTask(final String taskName,
                               final BiConsumer<ServerResponse, ServerError> consumer) {
        createSomeTask(taskName, true, consumer);
    }

    private void createSomeTask(final String taskName,
                                boolean retry,
                                final BiConsumer<ServerResponse, ServerError> consumer) {
        updateTaskStage((newStage, error)->{
            if(error!=null) {
                if (retry) {
                    createSomeTask(taskName, false, consumer); //The 'recursive' retry call
                    return;
                } else {
                    consumer.accept(null, error);//only after second failure
                    return;
                }
            }
            consumer.accept(new ServerResponse(),null);
        });

    }

    //re-uses existing task or starting a new one when the current is null / failed
    private void updateTaskStage(final BiConsumer<String, ServerError> consumer) {
        if(taskStage ==null || taskStage != "failed")
            consumer.accept(taskStage,null);
        else
        {
            taskStage = "started";
            consumer.accept(taskStage,null);
        }
    }

    class ServerResponse{}
    class ServerError{}
}





Aucun commentaire:

Enregistrer un commentaire