I have a web service to which data is posted. What I do is parse the json and store the data.
And my response is
render json: { success: true, message: "ok" }, status: 200
Active record takes about 10ms to complete the inserts. There are no views so rails returns something like 0.4 ms to render them. What I find strange are the response time, that are always different (ok, 20 ms up or down is ok, but those are the response times): 130ms, 62ms, 149ms, 71ms, 77ms, 150ms, 48ms, 72ms
My app is on Heroku (I only have new relic enabled, no other request). Does anyone know why the difference or a good way to test it? Maybe because of new Relic?
Related
(This question replaces this one, hopefully with better information.)
I've got three servers that I'm gonna call Alice, Charlie, and Harry (Harry being the server's actual nickname, so as not to confuse myself). They all talk to each other to perform quite a complicated authentication flow:
A client performs a sequence of three requests through Alice to Harry.
On the third one, Harry makes a call to Charlie.
Charlie is prone to timeouts during periods of heavy traffic. If it does, Harry returns a 503 with a Retry-After header to Alice.
Harry is returning a 503, I have confirmed that in its own logs.
Alice is not receiving a 503 but a 500, and without the header.
Alice's other clients (which I'm not in control of) treat a 500 the same as other errors, which is what I'm ultimately trying to fix.
Some extra information, such as I have been able to ascertain:
Alice proxies calls to Harry using RestClient, which uses Net::HTTP under the hood.
Using Net::HTTP directly gives the same result.
It's not environment specific; I have had this problem both in Production and Development.
I have been trying to simulate Alice using Postman, but haven't had any luck yet; Charlie's traffic is quieter at the moment, and I can't force or simulate a timeout, so so far I've only been getting successful 200 responses from Harry.
Fixing Charlie's timeouts would obviously be ideal, but I'm not in control of Charlie's hardware either.
Is there something I can change about Alice so it properly detects Harry's 503?
Or, is it possible that something about Harry is changing its 503 to a 500 after it's returned and logged?
Here's Alice's code for that third call, if it's likely to help, but nothing's jumping out at me; I have been wondering if RestClient or Net::HTTP has some configuration that I don't know about.
http_verb = :post
args = [ # actually constructed differently, but this is a reasonable mock up
'https://api.harry/path?sso_token=token',
'',
{
'content_type' => 'application/json',
'accept' => '*/*',
# some other app-specific headers
}
]
RestClient.send(http_verb, *args) do |response, request, result, &block|
# `result` is present and has a 500 code at the start of this block if Harry returns a 503.
#status_code = result.present? ? result.code : :internal_server_error
cors.merge!( response.headers.slice(:access_control_allow_origin, :access_control_request_method) )
#body = response.body
end
Turns out it's something way simpler and more obvious than anyone thought.
A separate error was raised in the middleware responsible for returning the 503. As with any other exception, this got rendered as a 500.
The thing that was causing it was a line that was supposed to tell the client to wait five seconds and try again:
response.headers['Retry-After'] = 5
... some middleware component was complaining of undefined method 'each' on 5:Fixnum, because it was expecting an Array where it wasn't a String; it started working when we changed 5 to '5'.
I am using Microsoft Graph and had successfully set up the ability to create subscriptions and receive push notifications. However, the process of creating a subscription is no longer working and I am stumped.
2018-01-25T23:32:41.694741+00:00 app[web.1]:
OData::ClientError (400 InvalidRequest:
"Subscription validation request failed.
Response must exactly match validationToken query parameter."
from "https://graph.microsoft.com/beta/subscriptions"):
Code to return validationToken in response. When I curl, my response is exactly as it should be.
def outlook_subscription
render plain: params[:validationToken]
head 200
end
Nothing has changed on our end. Since when did you start seeing this problem ? Did you deploy any new version of your (or the backed library) code ?
Please check the request/response in your logs and check if they both match (case sensitive).
This work for me!
def outlook_subscription
render json: params[:validationToken], content_type: "plain/text", status: 200
end
It takes my rails app an insane amount time to server ajax request. This is my test code
def test
respond_to do |format|
format.json { render json: '{"text" : "simpleJson"}' }
end
end
base on server log, it take my apps only 1ms to execute request :
but in browser, it is always recieved response in about 20k+ ms
When i change the json return to nothing ( format.json { render json: {} } ) the request only takes ~18ms. So I guess rails has some trouble when sending json back to client (because server log say the method test execute very fast). But I'm not sure about that because I'm very new to ruby and rails. My localhost is run by puma 3.10.0.
Any help would be appreciated.
Change from puma server to webrick solve my issue, but after doing some google the root cause of my problem maybe because I run rails on Window Subsystem Linux. At the moment, puma is slow in WSL.
Right now, upon a successful call to my Rails API Backend, I might do one of the following...
render json: {user_id: #user.id, token: token}
or
render json: {status: :success}
And upon an unsuccessful result, I may do something like
render json: {status: :failure, error: "The email or password entered is not correct."}
My question is... what's the best way to standardize this.
If my iOS app goes searching for a json dictionary value of dict[#"error"] it's not always going to find it. Should every single render message I have regardless of success... have a 'status' key, or an 'error' key or both.
Or is it better for the front end to deal with this, and if dict[#"error"]/dict[#"status"] happen to not exist... then it knows the back end did not have an error occur otherwise it would have said so?
The way you are rendering the responses is fine. On your client side, it's should be all about handling properly HTTP status codes.
render status: :ok -> should return a HTTP status code 200, which means a successful request. Then your client (iphone app) does know that with a successfull request you get the user id and token.
render status: :bad_request -> should return a HTTP status code 400, which means unsuccessfull request, then your client would know that an error occured, and based on your standards he can look up the error field of the json response
I had the similar question in terms of how do we standardize the JSON response.
By default Rails generates this sort of JSON from a post model,
posts: [
{
id: 22198,
title: "Using GitHub Pages To Host Your Website",
date: "2013-08-16 09:30:20",
},
{
id: 22196,
title: "Running Tests in Ruby on Rails – Treehouse Quick Tip",
date: "2013-08-15 14:30:48",
}
]
But is there any standard to power the Rails API for an iPhone APP?
What are the standards or typical success/failure response format an iOS developer would expect to see?
Here's the code for sending a json response associated with a working and non working status. Does anyone have recommendations for other resources? This isn't working. Thank you.
if #content.destroy
format.json { redirect_to #collection, status: :destroyed, notice 'Content was removed from collection.' }, :status => 200
else
format.json { render json #content.errors, status: :unprocessable_entity }, :status => 400
end
TL;DR: if you are using some JS framework, then look up how that framework wants success and failure response to look like, if you are rolling your own - then do whatever makes more sense for you.
Long version:
There are couple ways you can return response from rails to your web app. Rails by default returns status code 2xx for success and 4xx for failed requests. Some web frameworks such as Extjs, like to receive response with 200 code always and look at success key in the response to see if the request was successfult. If you are writing your own JS that utilizes XHR, then you can do whatever you want: its up to you how you architect your API. I find it useful to return json response from server with 200 code and set success key to true or false so in my callback JS i can write something like:
if(request.data.success){
successfulPost(response);
} else {
failed(response);
}
one of the reasons I prefer that approach is that, if there is an exception, then I can actually distinguish from record not being saved due to validation errors as opposed to bug in code that caused exception. But that is a personal preference and some may argue that error is error and it does not matter what caused it.