Search code examples
pythonmemcachedgmail-apihttplib2

Memcached not working with gmail API


I'm making a Django app that interfaces with the gmail API, and I'm trying to cache requests at the httplib2 level, which the docs for google-api-python-client: https://developers.google.com/api-client-library/python/guide/performance

The problem is that while the call is being made properly, and python is able to connect to memcached, it looks like keys are never found in memcached (if I'm reading the memcached output correctly). Code looks like this:

from django.core.cache import cache

flow = flow_from_clientsecrets(CLIENT_SECRET_FILE, scope=OAUTH_SCOPE)
http = httplib2.Http(cache=cache)

credentials = STORAGE.get()
if credentials is None or credentials.invalid:
    credentials = run(flow, STORAGE, http=http)

http = credentials.authorize(http)
gmail_client = build('gmail', 'v1', http=http)
batch = BatchHttpRequest()

messages = gmail_client.users().messages().list(userId='me', maxResults=1).execute()

if messages['messages']:
    for message in messages['messages']:
        batch.add(gmail_client.users().messages().get(userId='me', id=message['id'], format='metadata', fields="payload,threadId,id", metadataHeaders=['subject','date','to','from']), callback=messageCallback)

batch.execute()

And here is what the memcached logs look like:

## First time running the http request

<27 new auto-negotiating client connection
27: Client using the ascii protocol
<27 get :1:https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest
>27 END
<27 set :1:https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest 0 300 53713
>27 STORED
<27 get :1:https://www.googleapis.com/gmail/v1/users/me/messages?alt=json&maxResults=1
>27 END
<27 get :1:https://accounts.google.com/o/oauth2/token
>27 END
<27 delete :1:https://accounts.google.com/o/oauth2/token
>27 NOT_FOUND
<27 get :1:https://www.googleapis.com/gmail/v1/users/me/messages?alt=json&maxResults=1
>27 END
<27 delete :1:https://www.googleapis.com/gmail/v1/users/me/messages?alt=json&maxResults=1
>27 NOT_FOUND
<27 get :1:https://www.googleapis.com/batch
>27 END
<27 delete :1:https://www.googleapis.com/batch
>27 NOT_FOUND
<27 quit
<27 connection closed.


## Second time running the http request

<27 new auto-negotiating client connection
27: Client using the ascii protocol
<27 get :1:https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest
>27 sending key :1:https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest
>27 END
<27 get :1:https://www.googleapis.com/gmail/v1/users/me/messages?alt=json&maxResults=1
>27 END
<27 delete :1:https://www.googleapis.com/gmail/v1/users/me/messages?alt=json&maxResults=1
>27 NOT_FOUND
<27 get :1:https://www.googleapis.com/batch
>27 END
<27 delete :1:https://www.googleapis.com/batch
>27 NOT_FOUND
<27 quit
<27 connection closed.

Any idea what's going on?


Solution

  • The cache is working fine. The first request however is likely the only request that sends cache headers that allow caching.

    These log lines:

    <27 get :1:https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest
    >27 sending key :1:https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest
    

    indicate that the cache is working fine. This request does support caching, as this page sends the header Cache-Control: public, max-age=300, must-revalidate, no-transform.

    Other requests like the one to https://www.googleapis.com/batch send headers like Cache-Control: no-cache, no-store, max-age=0, must-revalidate.

    https://www.googleapis.com/gmail/v1/users/me/messages?alt=json&maxResults=1 sends:

    Date: Wed, 31 Dec 2014 22:05:35 GMT
    Expires: Wed, 31 Dec 2014 22:05:35 GMT
    Cache-Control: private, max-age=0
    

    so this page is immediately expired unless you send another request in the same second.