Race Conditions and Data Blocking
In DSPs, all communication between the client browser and the web server is asynchronous, which can lead to data conflicts resulting from competing parallel requests and responses. Uniface enables you to define data scope declarations that can prevent these conflicts.
In web applications, synchronous communication can be slow and unreliable. Once a request is sent, processing stops until a response has been received. This ensures that actions are performed in the correct sequence and that data remains synchronized on both the client and the server, but the application is frozen until the response is received. On the internet, the response may take a while or may not arrive at all.
Asynchronous communication makes parallel processing possible, which provides a more responsive and dynamic user experience. Once the request has been sent, the sender does not wait for a response before proceeding to the next request. For example, an end user can change the value of an input field while waiting for a search in another area of the web page.
Race Conditions
Requests are sent asynchronously, even when a response is required, and that response is also sent asynchronously. This can lead to race conditions in which data on the server is no longer synchronized with data on the client. Race conditions occur when multiple processes access and manipulate the same data concurrently, and the outcome of the execution depends on the particular order in which the access takes place.
For example, in a shopping cart application, the browser expects a response each time you click the Add to cart button. However, if you add another item before the browser has received the response for the first item, the response to the second request may arrive before the response to the first request. When the response to the first request finally arrives, it overwrites the previous response, showing only the first item has been added to the shopping cart. This is a race condition.
Synchronous Communication
Synchronous communication is two-way—once a request is sent, processing stops until a response has been received. Synchronous communication ensures that actions are performed in the correct sequence and that data remains synchronized on both the client and the server.
Synchronous communication between client and server in a web application is not desirable, because a server on the internet may take a while before it returns a response. All this time the enduser cannot continue using the web application. Furthermore, on the web there is no guaranty that the server returns a response at all, which would freeze the application.
Data Blocking
To prevent race conditions, Uniface blocks all data that is included in the request-response exchange. As long as data is blocked, it cannot be modified by the end user (it will be overwritten anyway) and it cannot be used in any other request-response cycles (the data is outdated). In effect, this provides the same behavior as synchronous communication, even though the actual request and response exchange on the communication level is asynchronous.
In Uniface, a request from the browser to the server includes all the data in the DSP instance. This includes occurrence state information (new, modified, deleted) for all entities and all field values, but excludes property values. The response from the server includes all the data in the DSP instance, including properties.
Uniface provides data scope declarations that specify the data that is part of trigger or operation requests. Any dependencies (input, output, sequence) between multiple requests are automatically managed. This can result in requests being delayed (thereby maintaining the execution sequence) or blocking the end user from entering data, or both. The 4GL developer has full control over data sent to and expected back from the server using scope declarations.
Since blocking mimics synchronous behavior and the web environment is unpredictable, inappropriate use of the scope definitions can still result in poor response time.
Guidelines
It therefore makes sense to minimize the data that is sent to the server (and therefore blocked), and limit the number of requests sent to the server. To do so you can use the following strategies:
- Maximize the amount of processing that takes place on the client. For example, any actions that change the appearance or layout of a web page should be limited to the client, as should actions that manipulate data or DSPs that are already available in the browser.
- Limit calls to the server to those that require access (CRUD) to the server's persistent data in, for example, a database
- Limit the amount of data that is included in
the request-response exchange by including a scope definition in triggers and
operations. You can define:
- Input scope—data to be included in the request set to the server.
- Output scope—data expected in the response to the browser. Only data that is defined in the output scope (including user data, operations, triggers and user events ) is blocked until the response is received.
For more information, see Input and Output Scope.
- Use multiple DSPs in a web page (using the DSPContainer widget) so that even if default blocking is applied, the user can continue with actions in other DSP instances of the web page.