{"id":574,"date":"2014-08-06T11:27:49","date_gmt":"2014-08-06T15:27:49","guid":{"rendered":"http:\/\/michaelseneadza.com\/blog\/?p=574"},"modified":"2014-08-06T11:27:49","modified_gmt":"2014-08-06T15:27:49","slug":"slow-responses-from-the-braintree-ruby-gem-try-this-fix","status":"publish","type":"post","link":"http:\/\/www.michaelseneadza.com\/blog\/2014\/08\/06\/slow-responses-from-the-braintree-ruby-gem-try-this-fix\/","title":{"rendered":"Slow Responses from the BrainTree Ruby Gem? Try This Fix."},"content":{"rendered":"<p>A few weeks ago I was tasked with trying to mitigate some timeout issues in a client&#8217;s Rails app making BrainTree calls.  This was becoming more of a problem as the client&#8217;s users built up more &#038; more history in BrainTree.  Apparently you can&#8217;t paginate the results or ask BrainTree to exclude certain parts of the response via the API.  So you can end up getting two years worth of transaction history that you don&#8217;t even care about attached to the piece of data that you do care about.  As you&#8217;ll see, parsing that potentially big ball of XML can become a problem.<\/p>\n<p>I started by outputting timestamps of the interactions with BrainTree to see if the slowness was on our side or theirs.  For many calls it was slow on both ends.  As an example, it might take 20 seconds for BrainTree to respond with the XML for the request and then another 28 seconds(!) for the BrainTree gem to parse that response.  My client&#8217;s server was set to issue a timeout after 45 seconds, so you can see how this was a problem (besides the fact that we wouldn&#8217;t want the users to have to wait so long for a response).<\/p>\n<p>As I dug a little deeper I discovered that the gem *should* use <a href=\"http:\/\/www.rubyinside.com\/ruby-xml-performance-benchmarks-1641.html\">the speedy LibXML gem<\/a> instead of the default REXML to do XML parsing. Unfortunately, we hadn&#8217;t installed LibXML.  So I installed and configured LibXML but I still got the same results.  So then I dug into the BrainTree gem&#8217;s code and discovered that there was a bug which was preventing it from finding LibXML.  <\/p>\n<p>The problem was a simple typo &#8212; <strong>the gem was looking for &#8220;::LibXml::XML&#8221; but it should have been checking for &#8220;::LibXML::XML&#8221;.  See the difference?  The &#8216;M&#8217; and the &#8216;L&#8217; need to be capitalized.<\/strong><\/p>\n<p>So I changed the gem&#8217;s code and ran my test again.  This time it still took the same amount of time for BrainTree to send us the XML response but <strong>the parsing only took 2 seconds instead of 28 seconds<\/strong>.<\/p>\n<p>I&#8217;ve submitted a pull request to BrainTree for this fix.  You can <a href=\"https:\/\/github.com\/MSeneadza\/braintree_ruby\/commit\/fc9f94a6b932109706c202248e1f562a3c658432#diff-d41d8cd98f00b204e9800998ecf8427e\">see my commit here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few weeks ago I was tasked with trying to mitigate some timeout issues in a client&#8217;s Rails app making BrainTree calls. This was becoming more of a problem as the client&#8217;s users built up more &#038; more history in BrainTree. Apparently you can&#8217;t paginate the results or ask BrainTree to exclude certain parts of&hellip; <a class=\"more-link\" href=\"http:\/\/www.michaelseneadza.com\/blog\/2014\/08\/06\/slow-responses-from-the-braintree-ruby-gem-try-this-fix\/\">Continue reading <span class=\"screen-reader-text\">Slow Responses from the BrainTree Ruby Gem? Try This Fix.<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","footnotes":""},"categories":[16],"tags":[20,22],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":830,"url":"http:\/\/www.michaelseneadza.com\/blog\/2021\/12\/20\/rails-7s-load_async-doesnt-play-well-with-multi-tenant-apps\/","url_meta":{"origin":574,"position":0},"title":"Rails 7&#8217;s load_async Doesn&#8217;t Play Well with Multi-Tenant Apps","date":"December 20, 2021","format":false,"excerpt":"Disclaimer: I can't speak for all multi-tenant apps but I suspect the vast majority of those which use separate DB schemas will run into the same issue I ran into. I was excited to try out the new Relation#load_async feature in Rails 7 to speed up some pages on SwingTradeBot.\u2026","rel":"","context":"In &quot;Technology&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":566,"url":"http:\/\/www.michaelseneadza.com\/blog\/2014\/05\/02\/calculating-standard-deviations-in-ruby-on-rails-and-postgresql\/","url_meta":{"origin":574,"position":1},"title":"Calculating Standard Deviations in Ruby on Rails (and PostgreSQL)","date":"May 2, 2014","format":false,"excerpt":"I need to calculate some Bollinger Bands (BBs) for SwingTradeBot, which is built in Rails 4. Here's a quick definition of Bollinger Bands: Bollinger Bands\u00ae are volatility bands placed above and below a moving average. Volatility is based on the standard deviation, which changes as volatility increases and decreases. So\u2026","rel":"","context":"In &quot;Technology&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":561,"url":"http:\/\/www.michaelseneadza.com\/blog\/2014\/04\/17\/ruby-rails-memoization-gems-memoist-vs-memoizable\/","url_meta":{"origin":574,"position":2},"title":"Ruby \/ Rails Memoization Gems Memoist vs. Memoizable","date":"April 17, 2014","format":false,"excerpt":"I was just adding some memoization to a Rails app and I was exploring the available gems. I'd used Memoist in the past on another project but I couldn't remember why I chose it over other gems. While researching today I found the Memoizable gem and thought that it looked\u2026","rel":"","context":"In &quot;Technology&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":557,"url":"http:\/\/www.michaelseneadza.com\/blog\/2014\/04\/06\/ive-finally-found-a-rails-4-x-blogging-engine-gem\/","url_meta":{"origin":574,"position":3},"title":"I&#8217;ve Finally Found a Rails 4.x Blogging Engine \/ Gem","date":"April 6, 2014","format":false,"excerpt":"I can't believe how difficult it's been to find a good solution for plugging a simple blog into an existing Rails app. I wanted to add a blog to SwingTradeBot, the new site I'm building but most answers to this question that I've found say to either use RefineryCMS or\u2026","rel":"","context":"In &quot;Blogging&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":52,"url":"http:\/\/www.michaelseneadza.com\/blog\/2003\/07\/05\/aols_journals\/","url_meta":{"origin":574,"position":4},"title":"AOL&#8217;s Journals","date":"July 5, 2003","format":false,"excerpt":"Here's a review of AOL's coming blogging tool, AOL Journals. It looks like they're doing it the right way. They're even including RSS\/XML (hello Blog*Spot). The article also has some interesting thoughts on the future of blogging.","rel":"","context":"In &quot;Blogging&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":483,"url":"http:\/\/www.michaelseneadza.com\/blog\/2005\/09\/02\/audio_of_new_orleans_mayors_wwl_radio_interview\/","url_meta":{"origin":574,"position":5},"title":"Audio of New Orleans Mayor&#8217;s WWL Radio Interview","date":"September 2, 2005","format":false,"excerpt":"CNN has been playing snippets of an interview that New Orleans Mayor Ray Nagin did last night on the radio. I've been trying to find the full audio online and oddly enough the BBC seems to be the only organization with the full audio posted (imagine that!). Nagin was dropping\u2026","rel":"","context":"In &quot;Current Events&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"http:\/\/www.michaelseneadza.com\/blog\/wp-json\/wp\/v2\/posts\/574"}],"collection":[{"href":"http:\/\/www.michaelseneadza.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.michaelseneadza.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.michaelseneadza.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.michaelseneadza.com\/blog\/wp-json\/wp\/v2\/comments?post=574"}],"version-history":[{"count":0,"href":"http:\/\/www.michaelseneadza.com\/blog\/wp-json\/wp\/v2\/posts\/574\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.michaelseneadza.com\/blog\/wp-json\/wp\/v2\/media?parent=574"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.michaelseneadza.com\/blog\/wp-json\/wp\/v2\/categories?post=574"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.michaelseneadza.com\/blog\/wp-json\/wp\/v2\/tags?post=574"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}