このような再試行可能な呼び出しを実装するScalaの方法は何ですか?

マウリシオリニャレス:

それでもScalaの初心者であり、次のコードを実装する方法を探しています。

@Override
public void store(InputStream source, String destination, long size) {

    ObjectMetadata metadata = new ObjectMetadata();
    metadata.setContentLength(size);
    final PutObjectRequest request = new PutObjectRequest(
            this.configuration.getBucket(), destination, source, metadata);

    new RetryableService(3) {

        @Override
        public void call() throws Exception {
            getClient().putObject(request);
        }
    };

}

RetryableServiceと同じ機能を実装するのにScalaで最適な方法は何でしょうか?

それは基本的にcallメソッドをN回呼び出します。それらすべてが失敗した場合、例外が発生し、成功した場合は続行します。これは何も返しませんが、値を返すことができる別のバージョンがあり(したがって、Javaには2つのクラスがあります)、Scalaの単一のクラス/関数で実行できると思います。

何か案は?

編集する

Javaの現在の実装は次のとおりです。

public abstract class RetryableService {

private static final JobsLogger log = JobsLogger
        .getLogger(RetryableService.class);

private int times;

public RetryableService() {
    this(3);
}

public RetryableService(int times) {
    this.times = times;
    this.run();
}

private void run() {

    RuntimeException lastExceptionParent = null;

    int x = 0;

    for (; x < this.times; x++) {

        try {
            this.call();
            lastExceptionParent = null;
            break;
        } catch (Exception e) {
            lastExceptionParent = new RuntimeException(e);
            log.errorWithoutNotice( e, "Try %d caused exception %s", x, e.getMessage() );

            try {
                Thread.sleep( 5000 );
            } catch (InterruptedException e1) {
                log.errorWithoutNotice( e1, "Sleep inside try %d caused exception %s", x, e1.getMessage() );
            }

        }

    }

    try {
        this.ensure();
    } catch (Exception e) {
        log.error(e, "Failed while ensure inside RetryableService");
    }

    if ( lastExceptionParent != null ) {
        throw new IllegalStateException( String.format( "Failed on try %d of %s", x, this ), lastExceptionParent);
    }   

}

public void ensure() throws Exception {
    // blank implementation
}

public abstract void call() throws Exception;

}
leedm777:

再帰+ ファーストクラス関数 by-nameパラメータ==すばらしい。

def retry[T](n: Int)(fn: => T): T = {
  try {
    fn
  } catch {
    case e =>
      if (n > 1) retry(n - 1)(fn)
      else throw e
  }
}

使い方は次のとおりです:

retry(3) {
  // insert code that may fail here
}

編集@themelの回答に触発されたわずかな変動1行少ないコード:-)

def retry[T](n: Int)(fn: => T): T = {
  try {
    fn
  } catch {
    case e if n > 1 =>
      retry(n - 1)(fn)
  }
}

もう一度編集:再帰によりスタックトレースにいくつかの呼び出しが追加されたので私は気になりました。何らかの理由で、コンパイラはキャッチハンドラで末尾再帰を最適化できませんでした。ただし、catchハンドラーにないテール再帰は最適化されます:-)

@annotation.tailrec
def retry[T](n: Int)(fn: => T): T = {
  val r = try { Some(fn) } catch { case e: Exception if n > 1 => None }
  r match {
    case Some(x) => x
    case None => retry(n - 1)(fn)
  }
}

もう一度編集する:どうやら私は戻ってきて、この答えに代替を追加し続けることを趣味にするつもりです。以下Optionは、を使用returnするよりも少し簡単な末尾再帰バージョンです、関数を短絡するために使用するのは慣用的なScalaではありません。

@annotation.tailrec
def retry[T](n: Int)(fn: => T): T = {
  try {
    return fn
  } catch {
    case e if n > 1 => // ignore
  }
  retry(n - 1)(fn)
}

Scala 2.10アップデート私の趣味と同じように、時々この答えを再訪します。導入されたScala 2.10 Tryは、末尾再帰的な方法で再試行を実装するクリーンな方法を提供します。

// Returning T, throwing the exception on failure
@annotation.tailrec
def retry[T](n: Int)(fn: => T): T = {
  util.Try { fn } match {
    case util.Success(x) => x
    case _ if n > 1 => retry(n - 1)(fn)
    case util.Failure(e) => throw e
  }
}

// Returning a Try[T] wrapper
@annotation.tailrec
def retry[T](n: Int)(fn: => T): util.Try[T] = {
  util.Try { fn } match {
    case util.Failure(_) if n > 1 => retry(n - 1)(fn)
    case fn => fn
  }
}

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

ユーザーが複数のタブで同じ JavaScript 呼び出しを実行しないようにする最善の方法は何ですか?

分類Dev

C ++で「可能な場合は参照による呼び出し」を行うことは可能ですか?

分類Dev

再帰的なテンプレート関数の最初の呼び出しで関数を実行するにはどうすればよいですか?

分類Dev

条件が満たされた後にhttpget callを実行する方法。そうでない場合は、角度4で再試行して再度呼び出します。

分類Dev

ここで行っているよりもwindow.setInterval()を使用するよりも、API呼び出しを再実行するためのよりクリーンな方法はありますか?

分類Dev

Typescript:条件付き戻り値の型で呼び出し可能な型を実装する方法は?

分類Dev

定期的な呼び出しのために実行可能ファイルをRAMにロードするにはどうすればよいですか?

分類Dev

SonarQubeでCASTのような分析を実装することは可能ですか?

分類Dev

Pythonで.NETのような属性を実装することは可能ですか?

分類Dev

luaでハノイの塔の適切な末尾呼び出しを行うことは可能ですか?

分類Dev

再試行の失敗呼び出しでデータが保持されないようにする-春の再試行

分類Dev

Ajax呼び出しを行う別の方法は何ですか?

分類Dev

この再帰関数を修正して、呼び出しが深くならないようにすることはできますか?

分類Dev

この非同期呼び出しが実行を一時停止するのはなぜですか?

分類Dev

RestTemplateJUnitで実際のRest呼び出しを行わないようにする

分類Dev

これは、AndroidアプリのAPI呼び出しを再試行ボタンを持っているための正しい方法ですか?

分類Dev

このプログラム内で想定されているように関数呼び出しが実行されないのはなぜですか?

分類Dev

この `getNoise`の呼び出しで、サブクラスの実装ではなく基本クラスの実装が使用されるのはなぜですか?

分類Dev

iOS(SwiftまたはObjectiveC)でこのようなソケット呼び出しを実現するにはどうすればよいですか?

分類Dev

このnameof()は本当に再帰的な呼び出しですか?

分類Dev

FromIterator :: from_iterのみを使用してfrom_iterの適切な実装を呼び出すことをRustはどのように理解しますか?

分類Dev

呼び出し可能な型の定義は何ですか?

分類Dev

MySQL Connector C ++ APIで1回の関数呼び出しで複数のクエリを実行する適切な方法は何ですか?

分類Dev

Fnを実装する型への参照が呼び出し可能として認識されないのはなぜですか?

分類Dev

reactreduxで依存API呼び出しを行う適切な方法は何ですか

分類Dev

これらのprint()呼び出しが間違った順序で実行されているように見えるのはなぜですか?

分類Dev

結果タイプが異なる2つのAsync <>呼び出しを並行して実行するにはどうすればよいですか?

分類Dev

javascript関数のpost呼び出しからrequest.getRequestDispatcherを実行することは可能ですか?

分類Dev

Pythonのリストはどのような順序で実行する必要がありますか。__contains__は__eq__を呼び出しますか?

Related 関連記事

  1. 1

    ユーザーが複数のタブで同じ JavaScript 呼び出しを実行しないようにする最善の方法は何ですか?

  2. 2

    C ++で「可能な場合は参照による呼び出し」を行うことは可能ですか?

  3. 3

    再帰的なテンプレート関数の最初の呼び出しで関数を実行するにはどうすればよいですか?

  4. 4

    条件が満たされた後にhttpget callを実行する方法。そうでない場合は、角度4で再試行して再度呼び出します。

  5. 5

    ここで行っているよりもwindow.setInterval()を使用するよりも、API呼び出しを再実行するためのよりクリーンな方法はありますか?

  6. 6

    Typescript:条件付き戻り値の型で呼び出し可能な型を実装する方法は?

  7. 7

    定期的な呼び出しのために実行可能ファイルをRAMにロードするにはどうすればよいですか?

  8. 8

    SonarQubeでCASTのような分析を実装することは可能ですか?

  9. 9

    Pythonで.NETのような属性を実装することは可能ですか?

  10. 10

    luaでハノイの塔の適切な末尾呼び出しを行うことは可能ですか?

  11. 11

    再試行の失敗呼び出しでデータが保持されないようにする-春の再試行

  12. 12

    Ajax呼び出しを行う別の方法は何ですか?

  13. 13

    この再帰関数を修正して、呼び出しが深くならないようにすることはできますか?

  14. 14

    この非同期呼び出しが実行を一時停止するのはなぜですか?

  15. 15

    RestTemplateJUnitで実際のRest呼び出しを行わないようにする

  16. 16

    これは、AndroidアプリのAPI呼び出しを再試行ボタンを持っているための正しい方法ですか?

  17. 17

    このプログラム内で想定されているように関数呼び出しが実行されないのはなぜですか?

  18. 18

    この `getNoise`の呼び出しで、サブクラスの実装ではなく基本クラスの実装が使用されるのはなぜですか?

  19. 19

    iOS(SwiftまたはObjectiveC)でこのようなソケット呼び出しを実現するにはどうすればよいですか?

  20. 20

    このnameof()は本当に再帰的な呼び出しですか?

  21. 21

    FromIterator :: from_iterのみを使用してfrom_iterの適切な実装を呼び出すことをRustはどのように理解しますか?

  22. 22

    呼び出し可能な型の定義は何ですか?

  23. 23

    MySQL Connector C ++ APIで1回の関数呼び出しで複数のクエリを実行する適切な方法は何ですか?

  24. 24

    Fnを実装する型への参照が呼び出し可能として認識されないのはなぜですか?

  25. 25

    reactreduxで依存API呼び出しを行う適切な方法は何ですか

  26. 26

    これらのprint()呼び出しが間違った順序で実行されているように見えるのはなぜですか?

  27. 27

    結果タイプが異なる2つのAsync <>呼び出しを並行して実行するにはどうすればよいですか?

  28. 28

    javascript関数のpost呼び出しからrequest.getRequestDispatcherを実行することは可能ですか?

  29. 29

    Pythonのリストはどのような順序で実行する必要がありますか。__contains__は__eq__を呼び出しますか?

ホットタグ

アーカイブ