Operation

This document covers the following topics:


How Natsubsrv Works

  • Natsubsrv uses a prefork model: a parent process starts the configured number of worker processes and supervises them.

  • Each worker runs its own Natural nucleus and runtime environment and handles requests independently.

  • All workers listen on the same TCP port, so incoming connections are distributed across them by the operating system.

  • A worker reads and validates the request, executes the requested Natural subprogram, and returns the result to the middleware.

  • Errors are written to the log and returned to the caller as an error response.

  • Natural's limit counters (MADIO, MAXCL, MAXERR, and the LT record-read limit) are reset before each request. Usage counted during an earlier request can therefore never cause an unrelated later request to fail.

Architecture Overview

The middleware and Natsubsrv can run on the same machine or on different machines; they communicate over TCP/IP, optionally secured with TLS.

Architecture Overview

Natural Session Mode

The Natural runtime used by Natsubsrv is initialized as a batch session and runs in server mode. The system variable *SERVER-TYPE is CALLNAT.

  • Subprograms must not expect interactive prompts or terminal I/O — statements such as INPUT or DISPLAY do not behave as in an interactive session.

  • Operations that rely on a terminal may fail or need to be adapted.

  • Use a report specification (REP notation) to emit logging and debugging output.

  • The report specification VIDEO is not supported.

A worker keeps its Natural session for its entire lifetime and serves any number of requests with it, so requests of different end users run one after another in the same session. Write your subprograms accordingly:

  • Keep them stateless. A subprogram must not carry data over from one call to the next, and it must not expect data left behind by an earlier call.

  • Do not depend on the worker. Which worker executes a request is decided by the operating system, so two consecutive calls of the same user may run in different sessions, and two calls of different users may run in the same one.

  • End your own transactions. Complete every unit of work with END TRANSACTION or BACKOUT TRANSACTION before the subprogram returns. The server does not commit for you. What it does do, unless you switch it off, is back out an open transaction before the next request starts (see Session Isolation Between Requests). Rely on that as a safety net, not as your transaction logic: a unit of work that is never committed is lost either way.

Session Isolation Between Requests

Because a worker reuses one Natural session for requests of different end users, the server resets that session at the start of every request: application-independent variables, global data areas, session parameters, the library search order and the retained sets are put back to a defined state, so no request can see what its predecessor left behind.

If your subprograms already clean up after themselves, you can disable the two parts of the reset to avoid unnecessary overhead.

Transaction Backout (backoutTransactionPerRequest)

Backs out the open transaction of every connected database before the request runs.

  • Values: true/false — Default: true

  • Environment variable: NATSUBSRV_BACKOUT_TRANSACTION_PER_REQUEST

  • Choosing a value: Leave it on unless you have measured that it costs you. Switch it off only where every subprogram reliably ends its own unit of work.

A Natural LOGON issues neither END TRANSACTION nor BACKOUT TRANSACTION. Without this option, a transaction that one request leaves open remains open when the next request starts. An END TRANSACTION in that next request then commits the previous end user's uncommitted work. The backout covers every database type in one step, Adabas and SQL databases alike, including the branches of a distributed transaction.

It only ends the transaction. Database connections stay open, so the option does not slow down the first database access of the next request.

Work File Close (closeWorkFilesPerRequest)

Closes the work files that the previous request left open.

  • Values: true/false — Default: true

  • Environment variable: NATSUBSRV_CLOSE_WORK_FILES_PER_REQUEST

  • Choosing a value: Leave it on unless your subprograms close their own work files or use none at all.

A LOGON closes no work file either. Without this option, a work file opened by one request stays open into the requests of other end users, who then write into it — and the records the first request wrote last stay in an unwritten buffer.

The close is performed at the end of a Natural session, not at the end of a program: it also closes work files configured with CLOSE MODE=USER, whose purpose is to outlive a program. On a subprogram server, it is the end of the request that a work file must not outlive.

Stopping and Restarting

  • Send SIGTERM (for example, kill <pid> or through your service manager) or press Ctrl+C (SIGINT) to stop the server. The parent process shuts its workers down in an orderly manner.

  • Requests that are already being processed are completed; the server then terminates.

  • Configuration changes take effect only after a restart. Change the configuration file or the environment variables and start the server again.

  • If a worker terminates unexpectedly, the event is written to the log. See Crash Reports.