Proyectos de Subversion Iphone Microlearning

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/**
2
 Copyright 2018 Google Inc. All rights reserved.
3
 
4
 Licensed under the Apache License, Version 2.0 (the "License");
5
 you may not use this file except in compliance with the License.
6
 You may obtain a copy of the License at:
7
 
8
 http://www.apache.org/licenses/LICENSE-2.0
9
 
10
 Unless required by applicable law or agreed to in writing, software
11
 distributed under the License is distributed on an "AS IS" BASIS,
12
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 See the License for the specific language governing permissions and
14
 limitations under the License.
15
 */
16
 
17
#import "FBLPromise+Retry.h"
18
 
19
#import "FBLPromisePrivate.h"
20
 
21
NSInteger const FBLPromiseRetryDefaultAttemptsCount = 1;
22
NSTimeInterval const FBLPromiseRetryDefaultDelayInterval = 1.0;
23
 
24
static void FBLPromiseRetryAttempt(FBLPromise *promise, dispatch_queue_t queue, NSInteger count,
25
                                   NSTimeInterval interval, FBLPromiseRetryPredicateBlock predicate,
26
                                   FBLPromiseRetryWorkBlock work) {
27
  __auto_type retrier = ^(id __nullable value) {
28
    if ([value isKindOfClass:[NSError class]]) {
29
      if (count <= 0 || (predicate && !predicate(count, value))) {
30
        [promise reject:value];
31
      } else {
32
        dispatch_after(dispatch_time(0, (int64_t)(interval * NSEC_PER_SEC)), queue, ^{
33
          FBLPromiseRetryAttempt(promise, queue, count - 1, interval, predicate, work);
34
        });
35
      }
36
    } else {
37
      [promise fulfill:value];
38
    }
39
  };
40
  id value = work();
41
  if ([value isKindOfClass:[FBLPromise class]]) {
42
    [(FBLPromise *)value observeOnQueue:queue fulfill:retrier reject:retrier];
43
  } else  {
44
    retrier(value);
45
  }
46
}
47
 
48
@implementation FBLPromise (RetryAdditions)
49
 
50
+ (FBLPromise *)retry:(FBLPromiseRetryWorkBlock)work {
51
  return [self onQueue:FBLPromise.defaultDispatchQueue retry:work];
52
}
53
 
54
+ (FBLPromise *)onQueue:(dispatch_queue_t)queue retry:(FBLPromiseRetryWorkBlock)work {
55
  return [self onQueue:queue attempts:FBLPromiseRetryDefaultAttemptsCount retry:work];
56
}
57
 
58
+ (FBLPromise *)attempts:(NSInteger)count retry:(FBLPromiseRetryWorkBlock)work {
59
  return [self onQueue:FBLPromise.defaultDispatchQueue attempts:count retry:work];
60
}
61
 
62
+ (FBLPromise *)onQueue:(dispatch_queue_t)queue
63
               attempts:(NSInteger)count
64
                  retry:(FBLPromiseRetryWorkBlock)work {
65
  return [self onQueue:queue
66
              attempts:count
67
                 delay:FBLPromiseRetryDefaultDelayInterval
68
             condition:nil
69
                 retry:work];
70
}
71
 
72
+ (FBLPromise *)attempts:(NSInteger)count
73
                   delay:(NSTimeInterval)interval
74
               condition:(nullable FBLPromiseRetryPredicateBlock)predicate
75
                   retry:(FBLPromiseRetryWorkBlock)work {
76
  return [self onQueue:FBLPromise.defaultDispatchQueue
77
              attempts:count
78
                 delay:interval
79
             condition:predicate
80
                 retry:work];
81
}
82
 
83
+ (FBLPromise *)onQueue:(dispatch_queue_t)queue
84
               attempts:(NSInteger)count
85
                  delay:(NSTimeInterval)interval
86
              condition:(nullable FBLPromiseRetryPredicateBlock)predicate
87
                  retry:(FBLPromiseRetryWorkBlock)work {
88
  NSParameterAssert(queue);
89
  NSParameterAssert(work);
90
 
91
  FBLPromise *promise = [[FBLPromise alloc] initPending];
92
  FBLPromiseRetryAttempt(promise, queue, count, interval, predicate, work);
93
  return promise;
94
}
95
 
96
@end
97
 
98
@implementation FBLPromise (DotSyntax_RetryAdditions)
99
 
100
+ (FBLPromise * (^)(FBLPromiseRetryWorkBlock))retry {
101
  return ^id(FBLPromiseRetryWorkBlock work) {
102
    return [self retry:work];
103
  };
104
}
105
 
106
+ (FBLPromise * (^)(dispatch_queue_t, FBLPromiseRetryWorkBlock))retryOn {
107
  return ^id(dispatch_queue_t queue, FBLPromiseRetryWorkBlock work) {
108
    return [self onQueue:queue retry:work];
109
  };
110
}
111
 
112
+ (FBLPromise * (^)(NSInteger, NSTimeInterval, FBLPromiseRetryPredicateBlock,
113
                    FBLPromiseRetryWorkBlock))retryAgain {
114
  return ^id(NSInteger count, NSTimeInterval interval, FBLPromiseRetryPredicateBlock predicate,
115
             FBLPromiseRetryWorkBlock work) {
116
    return [self attempts:count delay:interval condition:predicate retry:work];
117
  };
118
}
119
 
120
+ (FBLPromise * (^)(dispatch_queue_t, NSInteger, NSTimeInterval, FBLPromiseRetryPredicateBlock,
121
                    FBLPromiseRetryWorkBlock))retryAgainOn {
122
  return ^id(dispatch_queue_t queue, NSInteger count, NSTimeInterval interval,
123
             FBLPromiseRetryPredicateBlock predicate, FBLPromiseRetryWorkBlock work) {
124
    return [self onQueue:queue attempts:count delay:interval condition:predicate retry:work];
125
  };
126
}
127
 
128
@end