I am trying to implement this https://github.com/nuclearace/SwiftRateLimiter
Here is my code that is calling getDistanceBetweenLocations:
_ = circleQuery?.observe(.keyEntered, with: {(key: String?, location: CLLocation?) in
mapCoord[key!] = location?.coordinate //stores busID and it's coord in Dictionary
self.getBusinessData(bus: key!)
if (!searchBus.contains(key!)){
searchBus.append(key!)
self.getDistanceBetweenLocations(origLat: coordinates.lat, origLon: coordinates.lon, newLat: mapCoord[key!]!.latitude, newLon: mapCoord[key!]!.longitude, id: key!, done: {distance in
busDistance[key!] = distance
})
}
})
And this is the code that is calling the ratelimiter from the GitHub link above:
let GlobalDirectionsRateLimiter = RateLimiter(tokensPerInterval: 50, interval: .minute)
GlobalDirectionsRateLimiter.removeTokens(directionsChecked) {d in
print(d)
directions.calculate { (response, error) in
if let response = response, let route = response.routes.first {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "BusDataChanged"), object: nil)
done(route.distance/1609)
} else {
print("ERROR getting distance \(String(describing: error))")
//busDistance[id] = route.distance/1609
}
}
}
This is the removeTokens()
public func removeTokens(_ count: Double, callback: @escaping (Double) -> ()) {
if count > bucket.sizeOfBucket {
callback(-Double.infinity)
return
}
let now = Date().timeIntervalSince1970
if now - intervalStart >= bucket.interval {
intervalStart = now
tokensThisInterval = 0
}
guard count <= bucket.tokensPerInterval - tokensThisInterval else {
if firesImmediatly {
return callback(-Double.infinity)
}
queue.asyncAfter(deadline: DispatchTime.now() + ceil(intervalStart + bucket.interval - now)) {
func afterBucketRemove(tokensRemaining: Double) {
self.tokensThisInterval += count
callback(tokensRemaining)
}
self.bucket.removeTokens(count, callback: afterBucketRemove)
}
return
}
func afterBucketRemove(tokensRemaining: Double) {
tokensThisInterval += count
callback(tokensRemaining)
}
return bucket.removeTokens(count, callback: afterBucketRemove)
}
As I understand this the GlobalDirectionsRateLimiter limits tokensPerInterval to 50 in an interval of 1 minute. I guess my first question is on this line:
GlobalDirectionsRateLimiter.removeTokens(directionsChecked)
In the examples in the readme doc (directionsChecked) is a hard number.
I am assuming this is should be a count of doc being checked. Hence my directionsChecked variable which I am increasing by one for each loop. Am I missing something?
Looks like I fixed this. I defined
let GlobalDirectionsRateLimiter = RateLimiter(tokensPerInterval: 50, interval: .minute)
in a spot where it was redefined each time through the loop. So I defined it once at the top and it seems to be working
Although it's true I no longer get the error I also get my default distance for most of the businesses. If I change to this:
let GlobalDirectionsRateLimiter = RateLimiter(tokensPerInterval: 1, interval: .moreSec) moreSec is 1.25 seconds I get the error on the 51st item but all but 1 of the distances are correct. So the answer isn't quite correct....Still need help