ip2k / google-api-ruby-client

Automatically exported from code.google.com/p/google-api-ruby-client
Apache License 2.0
0 stars 0 forks source link

Result of discovered_api cannot be cached using Rails.cache #58

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Considering this piece of code:

      @client = Google::APIClient.new
      @client.authorization.access_token = token

      @calendar = Rails.cache.fetch('GoogleCalendar_calendar', expires_in: 30.minutes) do
        # discovered_api performs a HTTP request so let's cache it
        @client.discovered_api('calendar', 'v3')
      end

This throws the exception "TypeError (singleton can't be dumped)"

Rails.cache uses the Marshal class provided by Ruby: 
http://www.ruby-doc.org/core-1.9.3/Marshal.html

Would be nice to be able to marshal objects from google-api-ruby-client and 
thus be able to use them with Rails.cache (or whatever caching system that 
works with Marshal class).

Original issue reported on code.google.com by tkrotoff on 2 Sep 2012 at 1:41

GoogleCodeExporter commented 9 years ago
Agreed, it would be valuable to be able to dump these to a persistent cache, 
however, the use of singletons is unavoidable given what these classes actually 
do.

Marshaling these objects directly would be nice, but sadly, it's simply not 
something Ruby is capable of; so instead you're stuck caching the data the 
objects were derived from, rather than the objects themselves. And while I 
think it should be possible to do that right now, it's not something we've 
documented well at all, or really explicitly designed for, for that matter.

Most importantly, the best way to handle these is simply to avoid losing the 
reference to the actual object in the first place. You should be maintaining 
the object reference to these outside the request/response cycle. Indeed, you 
should keep a single client reference per thread, and be swapping only the 
authorization objects when you need to deal with a different user. Everything 
else in the client should be being reused. The client itself has a memory cache 
for discovery objects, so no need to duplicate that. You can just request the 
API you want and it'll do the right thing.

However, right now, even that best practice is neither particularly obvious, 
nor easy to get right if you try to do it. So while I won't be resolving this 
bug by going the Marshal route, it's definitely still something I need to take 
care of.

Original comment by bobaman@google.com on 2 Sep 2012 at 3:34

GoogleCodeExporter commented 9 years ago
Also, I should add, in cache-aware, production-ready usage forms, you should be 
setting client.authorization to nil, and instead passing an authorization 
object in as a parameter to the execute method, so that you don't have weird 
edge cases with a reused client object authorizing the wrong user. That way if 
you've got a bug, you simply make an unauthorized call instead of giving 
someone access to the wrong person's stuff.

Original comment by bobaman@google.com on 2 Sep 2012 at 3:42

GoogleCodeExporter commented 9 years ago
Thanks for you quick reply.

> The client itself has a memory cache for discovery objects, so no need to 
duplicate that

Does it cache also the results from multiple execute()?

Example:

         result = @client.execute!(
            api_method: @calendar.events.list,
            parameters: {
              calendarId: calendar_id,
              timeMin: time_min.utc.iso8601,
              timeMax: time_max.utc.iso8601,
              maxResults: 1000
            })

Original comment by tkrotoff on 2 Sep 2012 at 4:24

GoogleCodeExporter commented 9 years ago
No, API calls are not cached. It's something I'd like to implement, but I 
haven't found a good way to do it that would work well in a cross-framework 
way. But I'm very open to suggestions, so long as they're not Rails-specific. 
Rack-specific is fine though.

Original comment by bobaman@google.com on 2 Sep 2012 at 6:42

GoogleCodeExporter commented 9 years ago
As far as marshalling APIs, looks like it is possible with a tiny change. 
Playing around with implementing _.dump & _load to marshall as the original 
discovery doc & base URL. Seems to work OK, and for apps that either can't or 
won't reuse client instances (e.g. non-persistent workers for a queue) it can 
be a minor improvement...

Original comment by sba...@google.com on 3 Jan 2013 at 12:03

GoogleCodeExporter commented 9 years ago

Original comment by sba...@google.com on 26 Mar 2013 at 4:45