0

私は関数型プログラミング(とJava)を初めて使いました。それを使って素敵なものを作りたいと思います。機能インタフェースを使用して1回再試行してください

私はBiConsumer(java.util.function.BiConsumer)を使用してサーバーへの呼び出しを行っています。

既存のデータ(パブリックcreateSomeTask()を呼び出す)を使用してサーバーにリクエストを送信するコードを作成しようとしていますが、失敗した場合のみ、コネクタは再試行を1回しか実行しません。

コードは非同期ですが、privateのcreateSomeTask()もupdateTaskStage()を呼び出します。

問題は、現在の実装では、多くのcreateSomeTask()が で、コードがうまく表示されず、機能的なインターフェイスを使用したり、機能を拡張したりする方法があると確信しています。 BiConsumerまたはJava 8のlile、リフレクション、メソッド呼び出しなどの他の良い方法

以下のコードを参照してください。 誰かが私を助けてくれることを願っています。

//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{} 
} 
+0

あなたのコードはすでにBiConsumer(関数インタフェース)、ラムダ式を使用していますので、何をしたいのですか?いくつかの非同期ソリューションを探しているなら、私はCompletableFuture –

+0

はい、しかし、ここでの問題は "再試行"パラメータがtrueまたはfalseに設定された醜い再帰呼び出しです。 BiConsumerを拡張して、おそらく最初のコンシューマを自動的に呼び出されるフィールドとして追加する方法を探しています – Igal

答えて

0

あなたはupdateTaskStageに渡す前に正しいことを行う機能を構成することができますよう、消費者にretryフラグをチェックする理由はありません。

private void createSomeTask(
    String taskName, boolean retry, BiConsumer<ServerResponse, ServerError> consumer) { 

    BiConsumer<String, ServerError> direct 
     = (s, e) -> consumer.accept(e==null? new ServerResponse(): null, e); 

    BiConsumer<String, ServerError> actual = retry? 
     (string, error) -> { 
      if(error!=null) updateTaskStage(direct); else direct.accept(string, null); 
     }: 
     direct; 

    updateTaskStage(actual); 
} 

まず、関数が通過するのを作成しています提供された消費者に対するバックエンドの応答の翻訳。

次に、retrytrueの場合にのみ、関数はエラーの場合に2回目の試行を行う別の関数で作成されます。 2番目の試みでは、直接関数をupdateTaskStageに渡すことができ、再帰の必要性が排除されます。

それはretryパラメータがオプションであるために仮定されなかったようですが、問題を解決するためのあなたの試みの唯一の一環として、常に1回の再試行を実行を目的とする場合、あなたは今、それを取り除くことができます。

public void createSomeTask(
    String taskName, BiConsumer<ServerResponse, ServerError> consumer) { 

    BiConsumer<String, ServerError> direct 
     = (s, e) -> consumer.accept(e==null? new ServerResponse(): null, e); 

    BiConsumer<String, ServerError> actual= 
     (string, error) -> { 
      if(error!=null) updateTaskStage(direct); else direct.accept(string, null); 
     }; 

    updateTaskStage(actual); 
} 
関連する問題