Two configuration methods for Spartacus server-side rendering to introduce long API call timeout mechanism

Two methods, use config.backend.timeout = { 浏览器:...,服务器:...}, or can be more specifically configured, that is, based on Request granularity, by passing HTTP_TIMEOUT_CONFIG HttpContextToken to Angular HttpClient to configure for each specific request.

In SSR (Node.js), the timeout processing of external http calls that take too long is a particularly important improvement, because in Node.js, unlike browsers, there is no default external http call in the Node.js runtime environment. http call timeout (browsers usually timeout long http calls after a long time, such as 1 minute).

This configurable timeout logic is now implemented at the Angular Http interceptor level in Spartacus. That is to say, before the Spartacus SSR long API timeoutfunction is released, customers can implement similar logic by themselves, for example, by implementing Angular Http interceptors themselves.

Configuration code:

provideConfig({
    
     
  backend: {
    
     
    timeout: {
    
     
      server: 3_000,
      browser: 3_000
    }
  }
})

How to use a proxy server to create a delay effect for background API responses

First Install the http-proxy tool:npm install -g http-proxy

Then develop a http-proxy.js server file

const httpProxy = require('http-proxy');
const http = require('http');

const proxy = httpProxy.createProxyServer({
    
     secure: false });

const ENDPOINT_FOR_DELAY = 'consenttemplates';
const BACKEND_BASE_URL = 'https://jerry:9002';
const DELAY = 3000; // 手动硬编码的延时

/** custom predicate, whether we should delay a request */
const shouldDelay = (req) => {
    
    
  // Note: In browser there are 2 requests: preflight (OPTIONS) and actual request (GET).

  const result = req.url.includes(ENDPOINT_FOR_DELAY);
  result && console.log({
    
     delay: DELAY, url: req.url, method: req.method });
  return result;
};

http
  .createServer(function (req, res) {
    
    
    const forwardRequest = () =>
      proxy.web(req, res, {
    
     target: BACKEND_BASE_URL });
    const delay = shouldDelay(req) ? DELAY : 0;
    setTimeout(forwardRequest, delay);
  })
  .listen(9002);

Then start this proxy server:node http-proxy.js

Finally, specify the environment variable .env-cmdrcin CX_BASE_URL:

  "dev": {
    
    
    "CX_BASE_URL": "http://localhost:9002"
  },

Set timeout for a specific request:

import {
    
     HTTP_TIMEOUT_CONFIG, HttpTimeoutConfig } from `@spartacus/core`;
/* ... */
return this.httpClient.get('/some/api', {
    
    
  context: new HttpContext().set(
    HTTP_TIMEOUT_CONFIG, 
    {
    
     server: 15_000 } // value in milliseconds 
  )
})

When the timeout actually occurs, you can see the following warning message in the console:

Request to URL ‘${request.url}’ exceeded expected time of ${timeoutValue}ms and was aborted.

In summary, setting an explicit timeout for each outgoing http call is critical to the stability of a server-side rendered application running in NodeJS. Otherwise, if the backend API responds very slowly (or never responds), the server-rendered application will wait a long time (or forever) for a response. In this case, the memory allocated for the application is not freed, which causes memory leak issues.

Guess you like

Origin blog.csdn.net/i042416/article/details/130058460