Client Request Timeout between SenecaJS Service and Express API

1.6k views Asked by At

I am using SenecaJS to build a microservices based application. So far, I have conceptualized one microservice which consists of only one action yet. This action, when called, will execute a time-consuming shell command (approx. time consumed 3 minutes) and return as a response - the output of the shell command. My code files are available here: https://gist.github.com/ohmtrivedi/5a94841d25714f3cfd6aee260add97bb

So, I have been trying to make requests to this service in 2 different ways: First, I send a direct request to the service (which runs the plugin, osfp_tool) using cURL and as demonstrated here: http://senecajs.org/getting-started/#writing-microservices. Second, by referencing this tutorial: http://senecajs.org/getting-started/#web-server-integration, I wrote an Express API which communicates with my service (osfp_service). So, I send HTTP requests (using POSTMAN) to the Express API.

I used to receive Client Request timeout error in both cases. After some research, I came to know of timeout configuration in Seneca instance. So, I added a time configuration at 2 places - in the Seneca service (osfp_service) as well as in the Express API (app.js). Note that, I have set timeout to 300000ms or 5 mins. I have checked that the shell command takes about 3 mins, so timeout is set more than that. However, I still face Client Request timeout error as you can see below. I know that there is no error from the shell command execution, as on my serivce log, even after I get Client timeout Request error, the action completes its execution successfully which can be seen using console.log messages.

Log of script execution when attempting to send request directly to the service

Hope someone can help me in resolving this issue, stuck on it for a very long time now.

EDIT So, I have been playing around with timeout configuration. I was able to resolve the timeout error from osfp_service.js script by setting the timeout in seneca instance at the topmost level (https://gist.github.com/ohmtrivedi/5a94841d25714f3cfd6aee260add97bb#file-osfp_service-js-L8).

If I set timeout configuration in app.js in the same way (https://gist.github.com/ohmtrivedi/5a94841d25714f3cfd6aee260add97bb#file-app2-js-L26), then I still get Error 504: Client request timeout/Gateway timeout (https://drive.google.com/open?id=1El2JCy047dnm6PHlvU33d_mKPuIWUlfX).

If I set timeout configuration in app.js inside the transport object in seneca instance (https://gist.github.com/ohmtrivedi/5a94841d25714f3cfd6aee260add97bb#file-app1-js-L26), then I get Error 503: Response timeout/Service Unavailable (https://drive.google.com/open?id=1u6w7XyK9-vAJVhna_JnIQ4imRzOm_51T). I cannot understand why it says Service Unavailable, because the action does get executed and it even completes successfully.

I can't seem to understand the different behavior.

1

There are 1 answers

2
jack-y On BEST ANSWER

I also worked on timeout problems with Seneca. For my application, the solution was:

  1. Set the timeout in require('seneca'):

    let seneca = require('seneca')(
      {
        timeout: config.request_timeout,
        tag: ...
      }
    )
    
  2. Set the timeout in each act() call:

    seneca.act({timeout$: config.request_timeout, role: ...});
    

Hope this helps.

EDIT:

As found in this post, the transport timeout can also be configured:

let seneca = require('seneca')(
  {
    timeout: config.request_timeout,
    tag: ...,
    transport: {
      'web': { timeout: config.request_timeout },
      'tcp': { timeout: config.request_timeout }
    }
  }
);