// // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import NS_ASSUME_NONNULL_BEGIN typedef NS_ENUM(NSInteger, OWSOperationState) { OWSOperationStateNew, OWSOperationStateExecuting, OWSOperationStateFinished }; // A base class for implementing retryable operations. // To utilize the retryable behavior: // Set remainingRetries to something greater than 0, and when you're reporting an error, // set `error.isRetryable = YES`. // If the failure is one that will not succeed upon retry, set `error.isFatal = YES`. // // isRetryable and isFatal are opposites but not redundant. // // If a group message send fails, the send will be retried if any of the errors were retryable UNLESS // any of the errors were fatal. Fatal errors trump retryable errors. @interface OWSOperation : NSOperation @property (nullable) NSError *failingError; @property NSUInteger remainingRetries; #pragma mark - Subclass Overrides // Called one time only - (nullable NSError *)checkForPreconditionError; // Called every retry, this is where the bulk of the operation's work should go. - (void)run; // Called at most one time. - (void)didSucceed; // Called at most one time, once retry is no longer possible. - (void)didFailWithError:(NSError *)error; #pragma mark - Success/Error - Do Not Override // Complete the operation successfully. // Should be called at most once per operation instance. // You must ensure that `run` cannot fail after calling `reportSuccess`. - (void)reportSuccess; // Should be called at most once per `run`. // You must ensure that `run` cannot succeed after calling `reportError`, e.g. generally you'll write something like // this: // // [self reportError:someError]; // return; // // If the error is terminal, and you want to avoid retry, report an error with `error.isFatal = YES` otherwise the // operation will retry if possible. - (void)reportError:(NSError *)error; @end NS_ASSUME_NONNULL_END