JSON Performance in Rails - ruby-on-rails

I'm running a query on my index action in a Rails app, and if you look at the logs it's pretty fast:
Started GET "/apartments?within=-74.01798248291016%2C40.746346606483826%2C-73.8943862915039%2C40.79314877043915&per_page=500" for 127.0.0.1 at 2012-11-01 16:58:21 +0200
Processing by ApartmentsController#index as JSON
Parameters: {"within"=>"-74.01798248291016,40.746346606483826,-73.8943862915039,40.79314877043915", "per_page"=>"500"}
MONGODB (228ms) development['$cmd'].find({"count"=>"apartments", "query"=>{:status=>"available", :coordinates=>{"$within"=>{"$box"=>[[-74.01798248291016, 40.746346606483826], [-73.8943862915039, 40.79314877043915]]}}}, "fields"=>{:neighborhood_id=>0}}).limit(-1)
MONGODB (445ms) development['apartments'].find({:status=>"available", :coordinates=>{"$within"=>{"$box"=>[[-74.01798248291016, 40.746346606483826], [-73.8943862915039, 40.79314877043915]]}}}, {:neighborhood_id=>0}).limit(500).sort([[:qs, :desc]])
Completed 200 OK in 9737ms (Views: 8816.0ms)
If the DB query only takes 445ms, why does the JSON take almost 10 seconds to render and get sent back over the wire?
Is there a faster way to render the #apartments collection to JSON?

Use a different JSON serializer?
https://rubygems.org/gems/oj

Related

Saving a none string date to the database

I am developing an Rails 5.2 and Angular 7 app and I am using the NG-bootstrap datepicker. The problem with this is that it gives me an object rather than a string with the selected date and Rails will not save that to the database (or even permit it in the controller).
This is the response sent to the server:
Parameters: {"title"=>"hello", "company_id"=>"", "starts_at_date"=>{"year"=>2019, "month"=>1, "day"=>4}, "due_at_date"=>{"year"=>2019, "month"=>1, "day"=>2}, "description"=>"A small description", "project"=>{"company_id"=>"", "title"=>"hello", "description"=>"A small descriptio"}}
Completed 500 Internal Server Error in 0ms (ActiveRecord: 2.2ms)
How can I allow the following object to be permitted in the controller AND save it to the database?
{"year"=>2019, "month"=>1, "day"=>4}
Thankful for all help!

rails overall request time is longer than views+active record

I have this log entry:
Completed 200 OK in 519ms (Views: 306.2ms | ActiveRecord: 32.8ms)
How could that happen that the views rendering + active record is lower than the overall request time?
This is the object in action pack which holds the times:
=> #<ActiveSupport::Notifications::Event:0x007feeeba29590
#children=[],
#duration=742.621,
#end=2017-02-06 12:23:23 +0200,
#name="process_action.action_controller",
#payload=
{:controller=>"ProjectsController",
:action=>"update",
:params=>{"project"=>{"name"=>"Wwww.."}, "client_initiated_at"=>"Mon, 06 Feb 2017 10:23:22 GMT", "controller"=>"projects", "action"=>"update", "id"=>"3"},
:format=>:js,
:method=>"PUT",
:path=>"/workspaces/3",
:status=>200,
:view_runtime=>314.45606005598603,
:db_runtime=>85.04700000000001},
#time=2017-02-06 12:23:22 +0200,
#transaction_id="e0dfa141c53a0a641111">
In production the situation is worse:
Completed 200 OK in 3637ms (Views: 56.5ms | ActiveRecord: 79.8ms)
We are loosing almost 3.5 seconds on every request just because something else is there too...
Any idea where to start debuting the perf lost?
You should look into Rack-mini-profiler gem. It's pretty well made and gives great insight into what your looking for.
This is a pretty good tutorial about it

Rails production.log (using Passenger) being written to by multiple processes, can't be parsed

Here's a snippet of my production.log:
Started GET "/product/514034/754240" for XX.XX.202.138 at 2012-06-21 11:52:28 -0700
Started GET "/product/614409/666897" for XX.XX.228.38 at 2012-06-21 11:52:28 -0700
Processing by ProductsController#show as HTML
Parameters: {"category_id"=>"514034", "product_id"=>"754240"}
Processing by ProductsController#show as HTML
Parameters: {"category_id"=>"614409", "product_id"=>"666897"}
Logged in 2940659 via auth cookie
Logged in 585210 via auth cookie
[e3e3fc56bb6bd137741b269ee397683c] [2940659] Read fragment views/global-caches/header (0.7ms)
[e3e3fc56bb6bd137741b269ee397683c] [2940659] Rendered shared/_email_form.html.haml (0.7ms)
[d81bb986be5acc0277c0c9e11b414249] [585210] Read fragment views/global-caches/sharebar-message (0.7ms)
[d81bb986be5acc0277c0c9e11b414249] [585210] Rendered shared/_email_form.html.haml (0.7ms)
...
As you can see, it's logging two concurrent sessions of two different users simultaneously to the same log file. This makes it impossible to parse my logs and determine, for example, the time it took to generate each kind of page, because the entries are not in the expected order of:
Started GET "/URL/BLAH" for IP at DATE
... stuff...
Completed 200 OK in XXms (ActiveRecord: YY.Yms)
Instead I get an unpredictable interleaved log like this:
Started GET "/URL/BLAH" for IP at DATE
Started GET "/URL/BLAH" for IP at DATE
... stuff...
Completed 200 OK in XXms (ActiveRecord: YY.Yms)
...stuff...
Completed 200 OK in XXms (ActiveRecord: YY.Yms)
So it's impossible to match the "completeds" with the "Started."
What I'd like is a way to have each child process write to its own log or something. Or if it's possible a way to write the each pageview's log atomically, but that might be impossible or difficult or hurt performance.
Rails 3.2 provides nice option config.log_tag
You can add to your production.rb:
config.log_tags = [ lambda { Time.now.to_i }]
So each line in your logs will be prepended by numbers. Example:
[1351867173] Started GET "/" for 127.0.0.1 at 2012-11-02 16:39:33 +0200
[1351867173] Processing by RecipesController#main as HTML
Logs are still shuffled, but now we can normalize, order them.
sort -f -s -k1.1,1.11 production.log | sed 's/^.............//' > sorted_production.log
(Sorter by first symbols (by timestamp) and remove timestamp by sed)
Now logs are easy to analyze.
In addition there is fix on related issue https://github.com/rails/rails/pull/7317 in rails 3.2.9
So keep this in mind.
Sorry for bad English... )

What is the difference in "Processing by Contoller#method as */*" and "Processing by BillsController#show as HTML"

All of my rails 3.2.2 ActiveRecord methods are being executed twice. I noticed that each execution is being processed differently, see the examples I grabbed from the console below...
Started GET "/api/bills/Jeremy%20Fox" for 127.0.0.1 at 2012-03-20 23:16:43 -0400
Processing by BillsController#show as HTML
Parameters: {"username"=>"Jeremy Fox"}
BillsForUsers Load (2.4ms) SELECT "bills_for_users".* FROM "bills_for_users" WHERE "bills_for_users"."billusername" = 'Jeremy Fox'
Completed 200 OK in 47ms (Views: 11.2ms | ActiveRecord: 2.4ms)
Started GET "/api/bills/Jeremy%20Fox" for 127.0.0.1 at 2012-03-20 23:16:44 -0400
Processing by BillsController#show as */*
Parameters: {"username"=>"Jeremy Fox"}
BillsForUsers Load (1.1ms) SELECT "bills_for_users".* FROM "bills_for_users" WHERE "bills_for_users"."billusername" = 'Jeremy Fox'
Completed 200 OK in 33ms (Views: 28.1ms | ActiveRecord: 1.1ms)
Can anyone explain to me why all of my ActiveRecord methods are being executed twice and/or what the difference is between Processing by BillsController#show as HTML and Processing by BillsController#show as */*?
Thanks.
It turns out the problem was actually the JSONView Chrome extension. As it states in the options menu...
Use safe method to parse HTTP response (*)
(*) : safe method forces the browser to send an extra HTTP request to get the raw HTTP content.
After spending days trying to figure out what I was doing wrong in my code, it was actually just chrome!
Hope no one else runs into this stupid issue.
-Jeremy
I've been grappling with this same issue. The HTML Validator Chrome extension is also guilty (with none of the fine print.)
In my case, I'm calling a ModestModel-backed search request, so the first hit (and rendering) was succeeding, followed by a phantom 500 as my non-DB search model was out of scope and nil on the second request.
Thanks, Jeremy!

link_to :remote => :true fails in IE

I'm having a problem with remote links in IE, and I need to get it up & running soon cause the deadline is today :S
The problem is that we're using AJAX to make a remote call to an action and eval the returned javascript.
When making the call using Firefox for example it's working fine, if I do it in IE, the response is made as HTML request.
IE entry in development log
Started GET "/semantic/country/5" for 127.0.0.1 at Wed Sep 07 12:06:00
+0200 2011 Processing by Semantic::SemanticController#country as HTML
Parameters: {"id"=>"5"} Country Load (1.0ms) SELECT countries.*
FROM countries WHERE countries.id = 5 LIMIT 1 Rendered
semantic/semantic/country.js.erb (1.0ms) Completed 200 OK in 1785ms
(Views: 54.0ms | ActiveRecord: 1.0ms)
Firefox call in development log
Started GET "/semantic/country/5" for 127.0.0.1 at Wed Sep 07 12:06:00
+0200 2011 Processing by Semantic::SemanticController#country as JS
Parameters: {"id"=>"5"} Country Load (1.0ms) SELECT countries.*
FROM countries WHERE countries.id = 5 LIMIT 1 Rendered
semantic/semantic/country.js.erb (1.0ms) Completed 200 OK in 1785ms
(Views: 54.0ms | ActiveRecord: 1.0ms)
The code used to generate the link is the following (in HAML):
link_to #vacancy.country.name, semantic_country_url(#vacancy.country.id), {:remote => true, :class => 'ajax'}
The problem seems to be how IE interprets the data-remote stuff in the HTML5. Is there a solution around this?
without switching to jquery, beause I cannot rewrite all the javascript in the application.
EDIT
Found out that the IE browser sends the request twice now,first time a JS, which works fine, but second time as HTML.
don't run firebug AND IEdevtools at the same time...They both respond to the feedback messages and start acting weird in this case.
Once I shut down Firebug IE worked fine.

Resources