/* Enforces the global google books API limit of 1 request / user / second. Since all our requests look alike (we are all the same user, identified by an API key), we need to queue the requests up, and wait for a slot. This is done up to a maximum of wait time of 30 seconds, then a timeout abort is reported. */ func lookupISBNGlobal(ctx appengine.Context, country string, isbn isbn13.ISBN13) (*data.BookMetaData, error) { limiter := rate.New(ctx, 1*time.Second) var callErr error var result *data.BookMetaData closure := func() { result, callErr = lookupISBN(ctx, country, isbn) } if limitErr := limiter.Queue(globalAPIQueueLockKey, 30*time.Second, closure); limitErr == nil { return result, callErr } else { return nil, limitErr } }
/** Retrieves ISBN metadata from google books. The method enforces a limit of 1 lookup per 15 seconds. If a user exceeds this limit, the request is denied, and ErrAPIRejected is returned. */ func LookupISBN(ctx appengine.Context, country string, isbn isbn13.ISBN13) (*data.BookMetaData, error) { key := "lock:" + user.Current(ctx).ID limiter := rate.New(ctx, 15*time.Second) var callErr error var result *data.BookMetaData closure := func() { result, callErr = lookupISBNGlobal(ctx, country, isbn) } if limitErr := limiter.Queue(key, 10*time.Second, closure); limitErr == nil { return result, callErr } else { return nil, ErrorAPIRejected } }