Why would Gearman return empty http response - gearman

I have configured Gearman to accept request via http too.
I have a terminal with a running worker in which I confirm that workload is passed, and I receive a 200 status with expected headers, but Content-Length 0 and, of course, empty response body.
Any ideea why?
.. other than "The HTTP protocol should be considered experimental." :)

this is a bug in libgearman-server/plugins/protocol/http/protocol.cc implementation.
See https://bugs.launchpad.net/gearmand/+bug/1152707

Related

Request ending early on ExpressJS

router.route('...')
.get(function(req, res, next) {
// This job() function doing some *long* async task and end of the task calling 3th param as callback
job(param1, param2, function(response) {
// printing response to console perfectly
console.log("callback fired", response);
res.send("response");
});
});
And I'm making my request with curl.
$ curl ... -m 300
curl: (52) Empty reply from server
cURL is waiting for a response for a few minutes and then I'm getting empty reply error. cURL is giving this error before nodejs printing callback fired message.
Same error if I make this request with a browser or with Postman.
I'm sure there are no res.send(), res.end() functions inside job() async function. I stuck, how can I track and found the error?
There are two possible timeouts that could be affecting you. Without seeing the actual network trace (to see what happens when the request ends), I can't tell which timeout might be causing your issue. But, you can just address both of them and it should handle your issue.
First, curl has a timeout value. It is unclear what its default setting is, but you can set whatever value you want with:
curl --max-time 900
where the value is in seconds.
Second, the nodejs http server has a timeout where if no response is sent to an open request, it will close the socket (this keeps dead sockets from building up over time). You can see the doc for server.setTimeout() here. The default for the http server object is 2 minutes (I don't know if Express changes that at all).
The general idea is this:
server.setTimeout(10 * 60 * 1000); // set response timeout to 10 minutes
where the server object would be your http server object (not the Express app object).

why subsequent HTTP requests

My JavaScript makes that ajax call which retrieves a JSON array.
I am trying simulate long running HTTP REST call request that takes longer to return the results.
The way I do it is delay writing anything to the response object on the server side until 5 minutes elapsed since the request landed. After that I set the status to 200 and write the response with the JSON ending the stream.
Putting a breakpoint on the serve side I realize that the request shows up second time but the browser's Network tab does not show another request being made.
It may not be relevant but I am using browsersync middlewars to serve this JSON and write the bytes and end the response in setTimeout().
setTimeout(()=> {
res.statusCode = 200;
res.write(data);
res.end();
});
Question:
Anyone has any explanation as to why this is happening ? And if there is a way to simulate this in another ways ?
In most cases the browser should retry if connection is closed before response. This is a link to the details => HTTP spec Client Behavior if Server Prematurely Closes Connection
BTW it might help you use the chrome throttling options on the network section of dev tools (F12)

Node.js http GET request takes substantially longer than browser, REST client, et al

I am try to make a simple GET request in Node.js and the request takes 3-5 seconds to resolve whereas the same request in a browser or REST client takes ~400ms. The server to which I am making the request is controlled by our server team, but before I bother them with request/resource monitoring, I was going to ping the community to see if there were any "hey, check this setting first" kind of tips you guys could offer.
The code essentially forwards incoming requests to our server:
http.createServer(function (req, res) {
http.request({
host: "our.private.host",
port: 8080,
path: req.url,
headers: req.headers
}, function () {
res.end("DONE: " + Date.now());
}).end();
}).listen(8001);
I open my browser and type in the following URL:
http://localhost:8001/path/to/some/resource
... which gets forwarded on to the final destination:
http://our.private.host:8080/path/to/some/resource
Everything is working fine and I am getting the response I want, but it takes 3-5 seconds to resolve. If I paste the final destination URL directly in the browser or a REST client, it resolves quickly. I don't know much about our server, unfortunately - but I am looking more for node tips at this point. Note, the request pool isn't maxed out as I am only making 1 request at a time from my local machine.
The first step is gather some info on where the request is taking its time by looking at the exact timing of the network activity on your node server. You can do that by getting a tool that watches all network activity. I personally use Fiddler, but I know that WireShark is popular too.
Once that tools is installed and active, you can then see how long all these various steps in the process of your request are taking:
DNS request to resolve target IP address
Time to connect to the target server
Time to send the http request
Time to receive the http request
Time to send response back to original request
Understanding which of these operations is much longer than expected will give you an idea where to look further for the problem.
FYI, there are pre-built tools such as nginx that can do this type of proxying by just setting some values in a configuration file without any custom coding.

Is there a default timeout in Node.js for http.request?

In Node.js there is a default timeout for a server (for an incoming HTTP request) at 120000ms (2 minutes) (see HTTP's server.timeout documentation).
But if I want to do an HTTP request in Node.js (using http.request), looking at the documentation, I only find a function request.setTimeout() to set the timeout manually.
Anyone know if there is a default timeout for HTTP requests in Node.js? Or does Node.js try to send the HTTP request with no end?
You want to set the server.timeout property (it defaults to 120,000, as you've found).
Update: Node.js 13 has removed the default timeout:
https://nodejs.org/api/http.html#servertimeout
https://github.com/nodejs/node/pull/27558
I was also interested in this. By reading the code, Node.js uses Socket under the hood of http request (naturally). (The source link below is referring v8.8.0 at the point when I'm writing this)
https://github.com/nodejs/node/blob/master/lib/_http_outgoing.js
And Socket does not have the timeout by default by this document
https://nodejs.org/dist/latest-v6.x/docs/api/net.html#net_socket_settimeout_timeout_callback
And the source tells the same.
https://github.com/nodejs/node/blob/master/lib/net.js
No. There is no default timeout.
Node.js uses Socket under the hood of http request and socket does not have the timeout by default.
Use the {timeout: XX} parameter of http.request to configure a proper request timeout.

Connecting to a Reliable Webservice with Nodejs

My application needs to receive a result from Reliable Webservice. Here is the scenario:-
First I send a CreateSequence request. Then the server replies with a CreateSequenceResponse message. Next I send the actual request to the webservice.
Then the webservice send a response with 202 accept code and sends result in a later message. All these messages contain the header Connection: keep-alive.
I made request with http.ClientRequest. I could capture all responses except the result. http.ClientRequest fires only one response event.
How can I receive the message which contains the result?
Is there any way to listen to socket for remaining data (socket.on('data') did not work). I checked this with ReliableStockQuoteService shipped with Apache Synapse. I appreciate if someone can help me.
When you get the response event, you are given a single argument, which is an http.IncomingMessage, which is a Readable stream. This means that you should bind your application logic on the data event of the response object, not on the request itself.
req.on('response', function (res) {
res.on('data', console.log);
});
Edit: Here is a good article on how to make HTTP requests using Node.

Resources