Multiprocessing and Debugging

Like any other software tool, the FCF framework supports debugging tools, both on the server side and on the client side.

Debugging on the client side.

By default, all JS files that are transferred to the client side through the regular file reading controller fcf:NServer/NControllers/File.js undergo simplified compression (extra whitespace characters and comments are removed while maintaining the number of lines), disable compression for the current client, you can use the fcfManagement development control panel. (http://localhost:8080/fcfpackages/fcfManagement/development)

or run the following Javascript instructions to enable debug mode in the browser console.

> fcf.getContext().debug = true; > fcf.saveContext();

After that, all files received by the client will not be subjected to simplified compression.

Now you can start debugging. You can familiarize yourself with debugging templates.

Multiprocessing the FCF application and restarting NODEJS processes.

Before proceeding with the description of debugging on the server side, it is necessary to explain how the multiprocessing of FCF applications works. The built-in program fcfserver runs N number of NODEJS processes. The number of processes is determined by fcfserver's "processes" configuration parameter in the server.json file. Upon receiving requests from the client, fcfserver distributes the requests to separate NODEJS processes. Also, fcfserver monitors the status of running processes and restarts if necessary. The process is restarted in 4 cases:

  1. When explicitly requested to restart. Using the fcfManagement panel(http://localhost:8080/fcfpackages/fcfManagement/system):

    Or by sending a system message.

  2. When updating Javascript files or configuration files.
  3. When the process ends unexpectedly.
  4. When the memory limit is exceeded. This limit is set by the "maxMemory" configuration parameter in the server.json configuration file of the fcfserver application. By default, it is quite small and is 150Mb, so it should be changed if necessary.

Restarting the process occurs as follows. For each active NODEJS process, there are a couple of process startup configurations, and when restarting, it switches between these configurations in turn.

When the restart process begins, the replacement process is started first, after which it becomes active and all requests are sent to the new process, and the process that should be stopped ceases to be active, completes all incomplete tasks and is unloaded from memory.

Debugging on the server side.

To perform server-side debugging, you need to change the fcfserver configuration settings. You must set the launch options for NODEJS processes to run in debug mode. This is done by editing the "nodeOptions" configuration option in the server.json file. This parameter contains an array that contains an array of strings for launching NODEJS processes. Each element of this array corresponds to a separate process startup configuration. That is, the first two elements of the array correspond to the first pair of active interchangeable processes, the second to the second, and so on. Thus, if the "processes" parameter is equal to 2, then the size of the nodeOptions array should be equal to 4.

And so, let's set the fcfserver configuration for debugging by editing the server.json file. Add the --inspect option with the debug port.

File :server.json

{ // Server name "serverName": "main", // Main server name "mainServer": "main", // Server array // If there is only one element in the array (main server), then the port is not listened on. "servers": [ { // Server name "name": "main", // Server address "address": "127.0.0.1", // Server port "port": 3778 } ], // Number of the local server management port (int) // If 0 is specified, then a random free port is used "innerControlPort": 0, // Prefix of the log file path (string) "logFile": "log/server-log-", // The logging level (enum:[err|wrn|log|trc]) "logLevel": "log", // The life time of the log file of the server (days) "logLifeTime": 30, // User under which FCF processes are started. If the field is an empty string, then the process is executed from the current user. "user": "", // User password. Used only for Windows systems "password": "", // Length of the request queue "listenQueue": 128, // The value of keep-alive http requests "keepAliveTimeout": 5, // Maximum waiting time for receiving and sending a client packet (sec) "clientSocketTimeout": 5, // Maximum waiting time for receiving a request from the client (sec) "maxRequestTimeout": 300, // Maximum waiting time for receiving and sending a server packet (sec) "serverSocketTimeout": 5, // Maximum time to wait for a request to be sent from the server (sec) "maxResponseTimeout": 300, // Maximum time to wait for a child process to start (sec) "startTimeout": 600, // Maximum waiting time for a child process to stop (sec) "stopTimeout": 30, // Size of the intermediate data transfer buffer. This buffer is used // when receiving a request to transfer data to the client or in the case of a reboot // process when sending data to the client, in order to quickly release the process. // If the data size exceeds the set limit, then it is saved to disk. "transmissionBufferSize": 1000000, // The configuration of endpoints "endpoints": [ { // User under which FCF processes are started //"user": "www-data", // Used only for Windows systems //"password": "", // Length of the request queue //"listenQueue": 128, // Maximum waiting time for receiving and sending a client packet (sec) //"clientSocketTimeout": 5, // Maximum waiting time for receiving a request from the client (sec) //"maxRequestTimeout": 300, // Maximum waiting time for receiving and sending a server packet (sec) //"serverSocketTimeout": 5, // Maximum time to wait for a request to be sent from the server (sec) //"maxRequestTimeout": 300, // Maximum time to wait for a child process to start (sec) //"startTimeout": 600, // Maximum waiting time for a child process to stop (sec) //"stopTimeout": 30, // Size of the intermediate data transfer buffer. This buffer is used // when receiving a request to transfer data to the client or in the case of a reboot // process when sending data to the client, in order to quickly release the process. // If the data size exceeds the set limit, then it is saved to disk. //"transmissionBufferSize": 1000000, // The server interface address for IPv4, if omitted, must contain the value "none" (string) "bind4": "", // The server interface address for IPv6, if omitted, must contain the value "none" (string) "bind6": "::", // Number of the listening port (int) "port": 8080, // Handler parameters "handlers": [{ // Handler name "name": "application", // Maximum time to wait for a child process to start (sec) //"startTimeout": 30, // Maximum waiting time for a child process to stop (sec) //"stopTimeout": 30, // The host specified in the HTTP request that the handler will respond to. If omitted, it must contain an empty string. (string) "host": "", // URL the path specified in the HTTP request that the handler will respond to. If omitted, it must contain an empty string. (string) "path": "", // The number of concurrently running processes of handlers of constant work // without protection of memory leaks. The minimum value 2 (int) "processes": 1, // The FCF app. JavaScript script to run (string) "script": "fcf-example-moving-containers.js", // An array of arrays containing arrays of NDOEJS options for each process "nodeOptions": [["--inspect=17000"], ["--inspect=17001"]], // Maximum allowable memory size used by a handler process for processes with memory leak protection "maxMemory": 150, // Array of control message transmission ports. // The array is automatically filled up to the size specified in (process + processesLeakProtection) * 2, // applying an increment if at least one port is specified. // If the array is empty, then random free ports are used. "dataPorts": [] }] } ] }

Now let's open the chrome browser on the chrome://inspect debug settings page.

Add our two debug connections to the configuration (the configure button).

Now restart fcfserver. And our running process will appear on the chrome debug panel.