0

We have a Golang application running on AppEngine, that uses the following packages:

"cloud.google.com/go/storage"
apiStorage "google.golang.org/api/storage/v1"
"google.golang.org/appengine"
"google.golang.org/appengine/blobstore"
"google.golang.org/appengine/image"

General workflow

  • We get a signed URL from the golang application to upload a file to Google Cloud Storage
  • We send a PUT request to that URL to upload the file to a Google Cloud Storage bucket
  • Upon receiving the response for that PUT request, we retrieve a serving URL using the following code:

Code

ctx := appengine.NewContext(r)
objectName := fmt.Sprintf("%s", "/gs/"+bucketID+"/"+objectID)
key, err := blobstore.BlobKeyForFile(ctx, objectName)
client, _ := storage.NewClient(ctx)
_ , error := client.Bucket(bucketID).Object(objectID).Attrs(ctx)
res, err := image.ServingURL(ctx,appengine.BlobKey(key),&image.ServingURLOptions{Secure: true})

The problem we're having is that this works just fine 99% of the time (we get a serving URL back in the API client) but there are instances where we're getting back an error API Error 8 - OBJECT_NOT_FOUND (which happens less often if we wait more between the write from the PUT request and the read from the GET request to the serving URL endpoint).

Is that expected from the serving URL? Are there any workaround / mitigations we could put in place for this?

1 Answers1

0

The code you are using is correct but it is normal when you are calling an API that it will fail from time to time, like it is happening to you.

What you can do is improve your code, wrapping your API call in a exponential backoff algorithm which is an error handling algorithm. Using this algorithm, there is a time delay between requests that increase every time a request fails, before retrying the failed request.

Also found a different way to get serving base URL, which the user says it is working but I haven’t tried, maybe it can be useful for you.

gr7
  • 101