Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Caching of results #104

Open
cowboygneox opened this issue Oct 25, 2014 · 8 comments
Open

Caching of results #104

cowboygneox opened this issue Oct 25, 2014 · 8 comments

Comments

@cowboygneox
Copy link

Forgive me if this exists and I couldn't find it, but I think it would be awesome if an HTTP cache of some sort existed with the client so that we could traverse object relationships without making the same HTTP calls over and over.

Ex: I have a card, I would like to be able to call card.actions multiple times for various reasons, but the response of actions should be cached so that the HTTP call isn't made again.

Anyone else have thoughts on this?

Thank you very much for this gem. It follows the Trello API very well, and once I figured that out, I had no problem working with it.

@cowboygneox
Copy link
Author

I just added this to TInternet. It doubled the speed of my script. I could make a pull request if it's adequate:

module Trello
  Request = Struct.new "Request", :verb, :uri, :headers, :body
  Response = Struct.new "Response", :code, :headers, :body

  class TInternet
    class << self
      require "rest_client"

      @@cache = {}

      def execute(request)
        try_execute request
      end

      private

      def try_execute(request)
        begin
          if request
            result = execute_core request
            Response.new(200, {}, result)
          end
        rescue RestClient::Exception => e
          Response.new(e.http_code, {}, e.http_body)
        end
      end

      def execute_core(request)
        if request.verb.to_s == 'get' && !@@cache[request.uri.to_s].nil?
          @@cache[request.uri.to_s]
        else
          puts "#{request.verb} #{request.uri.to_s}"

          RestClient.proxy = ENV['HTTP_PROXY'] if ENV['HTTP_PROXY']
          response = RestClient::Request.execute(
            :method => request.verb, 
            :url => request.uri.to_s, 
            :headers => request.headers, 
            :payload => request.body, 
            :timeout => 10
          )

          if request.verb.to_s == 'get'
            @@cache[request.uri.to_s] = response
          end

          response
        end
      end
    end
  end
end

@cowboygneox
Copy link
Author

My changes obviously would work poorly if you POSTed data and then did a GET, so maybe the Trello::Client should have a caching parameter?

@jeremytregunna
Copy link
Owner

While I generally love this idea, I agree with your point about doing a GET after a POST. For that reason I don't think this is sufficient. However, if you'd be willing to take a look at resolving this problem, I'd like to have the ability to enable something like this in a future gem release.

@cowboygneox
Copy link
Author

I'm on it. I'll see if I can find time this weekend.

@rossta
Copy link
Collaborator

rossta commented Oct 27, 2015

I like this concept, but might consider it an extension, rather than built-in to the gem itself. Switching to an http client like Faraday offers the possibility for library to allow gem users to modify the request/response cycle through middleware. Gems like ocktokit and github use this approach; anyone using these clients can insert faraday-http-cache faraday middleware for http caching or something else for their own in-memory store if desired.

Thoughts on introducing this to ruby-trello?

@jeremytregunna
Copy link
Owner

👍 to that idea.

@cowboygneox
Copy link
Author

I (obviously) think this should be a feature in the gem. The accessibility of this gem would be greatly benefitted from it. Granted, it can be a difficult task to have full caching, but even if there was an option to enable it for GET requests, that would dramatically improve its speed.

Also, I could just do a better job of keeping the objects I want in memory, so as I write this, I'm seeing that this is certainly gold-plating, but you already have an awesome gem, why not decorate it a bit?

@hakunin
Copy link

hakunin commented Dec 17, 2015

I think it could be safely enabled in a client if you give it something like cache: true, expire_in: 1.minute. I really want to be able to just add a line somewhere and get the functionality. Its fiddly enough trying to make less requests already.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants