I am working with a process that uses the disk API to upload text files to Google Drive. This process often involves limiting limit values, even though the actual number of requests is nowhere near the user limit for the Drive API installed in the API console. In fact, setting a limit for each user does not affect the speed at which we receive exceptions. Is there a different limit (apart from the limit for each user) that determines the number of requests per second? Is it possible to adjust?
The process uses exponential rollback for these exceptions, so the actions are ultimately successful. We only make about 5 requests per second, and the limit for each user is set to 100.
Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden { "code" : 403, "errors" : [ { "domain" : "usageLimits", "message" : "Rate Limit Exceeded", "reason" : "rateLimitExceeded" } ], "message" : "Rate Limit Exceeded" }
EDIT: Here is a "simplified" version of the developer code. We use a domain delegation service account as described at: https://developers.google.com/drive/delegation .
package com.seto.fs.daemon; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.FileContent; import com.google.api.client.http.HttpBackOffIOExceptionHandler; import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler; import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler.BackOffRequired; import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.HttpResponse; import com.google.api.client.http.HttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.client.testing.util.MockBackOff; import com.google.api.client.util.DateTime; import com.google.api.client.util.ExponentialBackOff; import com.google.api.services.drive.Drive; import com.google.api.services.drive.Drive.Files.Insert; import com.google.api.services.drive.DriveScopes; import com.google.api.services.drive.model.ChildList; import com.google.api.services.drive.model.ChildReference; import com.google.api.services.drive.model.File.Labels; import com.google.api.services.drive.model.ParentReference; public class Test { private static final int testFilesCount = 100; private static final int threadsCount = 3; private static final AtomicInteger rateLimitErrorsCount = new AtomicInteger(0); private static final String impersonatedUser = "<impersonatedUserEmail>"; private static final String serviceAccountID = "<some-id>@developer.gserviceaccount.com"; private static final String serviceAccountPK = "/path/to/<public_key_fingerprint>-privatekey.p12"; public static void main(String[] args) throws Exception {
EDIT: We get this exception when we use one thread and put a 500 millisecond delay between each call. It seems that it’s impossible to get closer to the configuration of each user that we configured. Even by default, 10 requests per second look impossible. Why?
source share