Skip to content

Commit

Permalink
Add minimum time interval and default value to operation polling (#151)
Browse files Browse the repository at this point in the history
* Implement `startPollingOperations` extension function with default TimeInterval

* Implement `minimumTimePollingInterval`

* Write docs

* Replace magic value with minimumTimePollingInterval

* Add changes to changelog

* Fix remarks

* Fix delay start condition
  • Loading branch information
Hopsaheysa authored Mar 19, 2024
1 parent 8babbbc commit ae6acae
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 8 deletions.
16 changes: 12 additions & 4 deletions WultraMobileTokenSDK/Operations/Service/WMTOperationsImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ class WMTOperationsImpl<T: WMTUserOperation>: WMTOperations, WMTService {
private var isPollingPaused: Bool { return pollingTimer?.isValid == false }
private let pollingLock = WMTLock()
private var notificationObservers = [NSObjectProtocol]()
private let minimumTimePollingInterval = 5.0

/// Operation register holds operations in order
private lazy var operationsRegister = OperationsRegister { [weak self] ops, added, removed in
Expand Down Expand Up @@ -364,8 +365,17 @@ class WMTOperationsImpl<T: WMTUserOperation>: WMTOperations, WMTService {
refreshOperations()
}

D.print("Operations polling started with \(interval) seconds interval")
pollingTimer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { [weak self] _ in
// Set the minimum TimeInterval
var adjustedInterval: TimeInterval
if interval < minimumTimePollingInterval {
D.warning("Operations polling interval: \(interval), must not be set below \(minimumTimePollingInterval) to prevent server overload.")
adjustedInterval = minimumTimePollingInterval
} else {
adjustedInterval = interval
}

D.print("Operations polling started with \(adjustedInterval) seconds interval")
pollingTimer = Timer.scheduledTimer(withTimeInterval: adjustedInterval, repeats: true) { [weak self] _ in
self?.refreshOperations()
}
}
Expand Down Expand Up @@ -396,8 +406,6 @@ class WMTOperationsImpl<T: WMTUserOperation>: WMTOperations, WMTService {
return
}

let requestStartDate = Date()

networking.post(data: .init(), signedWith: .possession(), to: WMTOperationEndpoints.List<T>.endpoint) { response, error in

assert(Thread.isMainThread)
Expand Down
14 changes: 13 additions & 1 deletion WultraMobileTokenSDK/Operations/WMTOperations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public protocol WMTOperations: AnyObject {
///
/// If operations are already polling this call is ignored and
/// polling interval won't be changed.
/// - Parameter interval: Polling interval
/// - Parameter interval: Polling interval, minimum is 5s
/// - Parameter delayStart: When true, polling starts after
/// the first `interval` time passes
func startPollingOperations(interval: TimeInterval, delayStart: Bool)
Expand Down Expand Up @@ -155,6 +155,18 @@ public extension WMTOperations {
func authorize(qrOperation: WMTQROperation, authentication: PowerAuthAuthentication, completion: @escaping (Result<String, WMTError>) -> Void) -> Operation {
return authorize(qrOperation: qrOperation, uriId: "/operation/authorize/offline", authentication: authentication, completion: completion)
}

/// Starts the operations polling.
///
/// Deafula implementation of startPollingOperations
/// The `interval` is set to 7 seconds, with a minimum value of 5 seconds.
///
/// - Parameters:
/// - interval: Default is set to 7 seconds, with a minimum value of 5 seconds.
/// - delayStart: Default is set to false and polling starts immediately.
func startPollingOperations() {
return startPollingOperations(interval: 7, delayStart: false)
}
}

public typealias GetOperationsResult = Result<[WMTUserOperation], WMTError>
Expand Down
6 changes: 3 additions & 3 deletions WultraMobileTokenSDKTests/IntegrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -356,16 +356,16 @@ class IntegrationTests: XCTestCase {
XCTAssertFalse(ops.isPollingOperations)
let delegate = OpDelegate()
delegate.loadingCountCallback = { count in
if count == 4 {
if count == 3 {
self.ops.stopPollingOperations()
exp.fulfill()
}
}
ops.delegate = delegate
ops.startPollingOperations(interval: 1, delayStart: false)
ops.startPollingOperations()
XCTAssertTrue(ops.isPollingOperations)

waitForExpectations(timeout: 20, handler: nil)
waitForExpectations(timeout: 30, handler: nil)

XCTAssertFalse(ops.isPollingOperations)
}
Expand Down
1 change: 1 addition & 0 deletions docs/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 1.10.0

- Removed `currentServerTime` property [(#148)](https://github.com/wultra/mtoken-sdk-android/pull/139)
- Added default and minimum pollingInterval [(#151)](https://github.com/wultra/mtoken-sdk-ios/pull/151)

## 1.9.0 (Jan 24, 2024)

Expand Down
10 changes: 10 additions & 0 deletions docs/Using-Operations-Service.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ if (!operationsService.isPollingOperations) {
}
```

### Default and Minimum TimeInterval Enforcement

For convenience, there is a default implementation where you can omit the polling interval and it is automatically set to 7 seconds. If you specify an interval below 5 seconds, it will be automatically adjusted to 5 seconds to prevent server overload.

### Setting up a delegate

To receive the result of the polling, set up a delegate.

<!-- begin box warning -->
Expand Down Expand Up @@ -148,6 +154,10 @@ class MyOperationsManager: WMTOperationsDelegate {
Polling behavior can be adjusted by the `pollingOptions` parameter when [creating an instance](#creating-an-instance) of the service.
<!-- end -->

### Best Practices and Recommendations

For optimal server performance, consider adjusting polling intervals based on your application's requirements. For instance, when push notifications are enabled, it's advisable to double the polling interval to minimize server load.

## Approve an Operation

To approve an operation use `WMTOperations.authorize`. You can simply use it with the following examples:
Expand Down

0 comments on commit ae6acae

Please sign in to comment.