Skip to main content
Version: 20 R5

Client/Server Optimization

4D provides optimizations for ORDA requests that use entity selections or load entities in client/server architectures. These optimizations speed up the execution of your 4D application by reducing drastically the volume of information transmitted over the network. They include:

  • the optimization context
  • the ORDA cache

Supported architectures

ORDA client/server architectures that support the optimization are:

Optimization context

The optimization context is based upon the following implementations:

Compatibility Note

Contexts handled in connections established through Open datastore can only be used between similar main versions of 4D. For example, a 4D 20.x remote application can only use contexts of a 4D Server 20.x datastore.

Example

Given the following code:

 $sel:=$ds.Employee.query("firstname = ab@")
For each($e;$sel)
$s:=$e.firstname+" "+$e.lastname+" works for "+$e.employer.name // $e.employer refers to Company table
End for each

Thanks to the optimization, this request will only get data from used attributes (firstname, lastname, employer, employer.name) in $sel from the second iteration of the loop.

Reusing the context property

You can increase the benefits of the optimization by using the context property. This property references an optimization context "learned" for an entity selection. It can be passed as parameter to ORDA functions that return new entity selections, so that entity selections directly request used attributes to the server and bypass the learning phase.

You can also create contexts using the .setRemoteContextInfo() function.

The same optimization context property can be passed to unlimited number of entity selections on the same dataclass. All ORDA functions that handle entity selections support the context property (for example dataClass.query() or dataClass.all()). Keep in mind, however, that a context is automatically updated when new attributes are used in other parts of the code. Reusing the same context in different codes could result in overloading the context and then, reduce its efficiency.

A similar mechanism is implemented for entities that are loaded, so that only used attributes are requested (see the dataClass.get() function).

Example with dataClass.query():

 var $sel1; $sel2; $sel3; $sel4; $querysettings; $querysettings2 : Object
var $data : Collection
$querysettings:=New object("context";"shortList")
$querysettings2:=New object("context";"longList")

$sel1:=ds.Employee.query("lastname = S@";$querysettings)
$data:=extractData($sel1) // In extractData method an optimization is triggered
// and associated to context "shortList"

$sel2:=ds.Employee.query("lastname = Sm@";$querysettings)
$data:=extractData($sel2) // In extractData method the optimization associated
// to context "shortList" is applied

$sel3:=ds.Employee.query("lastname = Smith";$querysettings2)
$data:=extractDetailedData($sel3) // In extractDetailedData method an optimization
// is triggered and associated to context "longList"

$sel4:=ds.Employee.query("lastname = Brown";$querysettings2)
$data:=extractDetailedData($sel4) // In extractDetailedData method the optimization
// associated to context "longList" is applied

Entity selection-based list box

Entity selection optimization is automatically applied to entity selection-based list boxes in 4D client/server desktop applications, when displaying and scrolling a list box content: only the attributes displayed in the list box are requested from the server.

A specific "page mode" context is also provided when loading the current entity through the Current item property expression of the list box (see Collection or entity selection type list boxes). This feature allows you to not overload the list box initial context in this case, especially if the "page" requests additional attributes. Note that only the use of Current item expression will create/use the page context (access through entitySelection\[index] will alter the entity selection context).

Subsequent requests to server sent by entity browsing functions will also support this optimization. The following functions automatically associate the optimization context of the source entity to the returned entity:

For example, the following code loads the selected entity and allows browsing in the entity selection. Entities are loaded in a separate context and the list box initial context is left untouched:

 $myEntity:=Form.currentElement //current item expression
//... do something
$myEntity:=$myEntity.next() //loads the next entity using the same context

Preconfiguring contexts

An optimization context should be defined for every feature or algorithm of your application, in order to have the best performances. For example, a context can be used for queries on customers, another context for queries on products, etc.

If you want to deliver final applications with the highest level of optimization, you can preconfigure your contexts and thus save learning phases by following these steps:

  1. Design your algorithms.
  2. Run your application and let the automatic learning mechanism fill the optimization contexts.
  3. Call the dataStore.getRemoteContextInfo() or dataStore.getAllRemoteContexts() function to collect contexts. You can use the entitySelection.getRemoteContextAttributes() and entity.getRemoteContextAttributes() functions to analyse how your algorithms use attributes.
  4. In the final step, call the dataStore.setRemoteContextInfo() function to build contexts at application startup and use them in your algorithms.

ORDA cache

For optimization reasons, data requested from the server via ORDA is loaded in the ORDA remote cache (which is different from the 4D cache). The ORDA cache is organized by dataclass, and expires after 30 seconds.

The data contained in the cache is considered as expired when the timeout is reached. Any access to expired data will send a request to the server. Expired data remains in the cache until space is needed.

You can force entity selection data in the ORDA cache to expire at any moment by using the refresh() function.

By default, the ORDA cache is transparently handled by 4D. However, you can control its contents using the following ORDA class functions: