Home » News » 2020 News » DataFlex WebApp Process Pooling Demo

DataFlex WebApp Process Pooling Demo

When writing Web Applications using the DataFlex WebApp Framework developers new to the paradigm often struggle to understand how the “state” of the application needs to be managed (I know I did!). The problem stems from Process Pooling.

DataFlex WebApp Process Pooling

In such Web Applications you cannot trust values which are stored in global variables or regular properties, or indeed the global table buffers; you can only rely on “web properties” or Data Dictionary values, since these are “synchronised” by the framework – restored to what you expect – on each round-trip between the client (generally a web browser such as Chrome, Firefox, Safari, or Internet Explorer) and the process which is invoked to service the request on the server.

DataFlex web apps generally use a “Process Pool”, rather than starting up a new process to service a given user’s session. This allows DataFlex web apps to be both highly responsive and highly scalable. When the service is started, it fires up a number of instances of the application, as defined in the Web Application Server Administrator for that app: right-click on the app in the left-hand pane, select “Web Application Properties” and click on the “Process Pooling” tab to see those settings (whether to use process pooling at all for a given app, the maximum and minimum pool size and on what basis it should be reloaded).

As soon as a user (technically a “client”) makes a request, it is handed off by the DataFlex Web Application Server to one of those processes to service it, which are used in a round-robin fashion. This means that the server process which services one request may not be the one which services the next. Thus if you store some value in a global variable, or a “regular” property, on one request to the server process, it may well not have the that value in it on subsequent requests (as Clint Eastwood playing “Dirty Harry” might say: “You’ve got to ask yourself a question: ‘do I feel lucky?’ Well, do ya, punk?“).

In order to preserve that “state” (the value you want to store), you need to use a web property, which you define by first creating the property in the usual way: “Property {type} {name}” and then locating that in the Studio’s code explorer (right-click on it and choose “Locate in Code Explorer”), then right-click on it in the Code Explorer pane and select “Web Property”, which will offer you the choice of “False” (i.e not a web property at all), “Client”, “Server” or “Server Session”. Choosing one of these will apply the meta-tag: “{ WebProperty=Client }” (or =Server, or =ServerSession) in the line above the property. (We won’t discuss the differences between these here except to say that “Client” properties are sent back to the browser, so might be changed by black-hat individuals messing with the value, while “Server” one’s are not, so are more secure.)

You can initialise such a property in the usual way with “Set {propertyName} to {value}, however once the process has started up and is serving requests from users, you access those properties using “WebSet {propertyName} to {value}” to store a value in it and “WebGet {propertyName} to {variable}” to retrieve that value again.

The Process Pool Demo

To help clarify what is going on here I have written a small Web View (which includes a Web Modal Dialog in the same file, for simplicity) which illustrates this:

web view example for process pooling
The Process Pool Demo view – see it live here.

You can drop this into any WebApp (put it in your workspace’s AppSrc folder, then in the DataFlex Studio’sWorkspace Explorer” pane, right-click and select “Add Component(s) to <WebApp.src>…”, then navigate to “ProcPoolDemo.wo”). You can find the code listing at Process Pool Demo on DataFlex.wiki and the zip file can be downloaded from here.

Clicking the buttons at the bottom will initiate various client/server round-trips and you can see which process services each. The value of a global variable (giRandom), a “regular” property (piRandom) and the value of a randomly selected recum in the Flexerrs table global buffer are displayed for the last-accessed server process, while the list shows the pool of processes with the last-accessed one being the selected row after each round-trip.

The process pool information is also updated on each round-trip; if you increase the minimum pool size in Web Application Server Administrator while accessing the app in a browser, and click repeatedly on the “Call Server” button, you will see the processes being added to the list in there (if you can click quickly enough!).

If you run it under the debugger, you will see that only a single process is running, regardless of the pool settings, and none of the global information will change as you click the buttons, illustrating why you must test web applications outside the debugger – within it you are simply not exposing your app to the problems it will encounter in live usage.

Now you might be thinking “But if I only have one server process in the pool, then I’ll be safe to use global variables and the like!“, but even that might catch you out. A single process can be servicing many users at the same time (which is what makes DataFlex web apps so scalable) and between your different server round-trips another user may have taken action which will change things (especially the global table buffers), so even there you must not rely on them. In web apps don’t use any global variables or “regular” properties which the app can change at run-time and never rely on the contents of the global buffers: use Data Dictionaries instead.

This post was inspired by the post Sample View showing effects of process pooling on the Data Access forums.

DataFlex Process Pooling
Watch the DataFlex Process Pooling video

Want to know more about process pooling with DataFlex? Watch the free Process Pooling with DataFlex video course on the DataFlex Learning Center