Sharing leads to performance

Following this blog post about the new concept of shareable entity selections and the subsequent discussions on the forum, we’ll now take the time to explain how ORDA fits into the future.

Several months ago, we proudly introduced ORDA and all its new concepts.

You learned that in ORDA, EVERYTHING is an object:


Beyond this, the days when you were stuck with a single current selection per table, are over. You can manage as many entity selections as you want. And since everything is an object, you’re ready for code that’s easier to handle, generic coding, and serialization to communicate with other software.

Did you know that all of this comes out-of-the-box with 4D? There’s no technology stack to handle and no headaches with a complex framework.

4D v17 also included another very important option: share data between processes with shared objects and collections. It’s now very easy to share various data between preemptive processes.

4D is confidently leading you towards a world of multi-threading, taking a lot of advantage of processor capabilities to improve performance in your applications.

The best performance and easiest coding rely on this equation: objects + sharing.

And then comes the concept of shareable entity selections

let’s study a first use case

You may have already discovered all of the advantages of the WORKER to run tasks in preemptive mode. So far only, shared objects and shared collections could be passed to it as a reference.

Imagine the benefits you could reap by passing entity selections as a reference, too … just like any shared item.

Here’s an appropriate use case:

1- Identify paid invoices and unpaid invoices

2- Send acknowledgment emails to customers for their paid invoices and reminder emails for their unpaid ones. Because this task is potentially time-consuming, we want to delegate it to a WORKER in asynchronous mode.

The code could look like this:

var $paid; $unpaid : cs.InvoicesSelection
//Get entity selections for paid and unpaid invoices
$paid:=ds.Invoices.query("status=:1"; "Paid")
$unpaid:=ds.Invoices.query("status=:1"; "Unpaid")

//Pass entity selections as references to the WORKER
CALL WORKER("mailing"; "sendMails"; $paid; $unpaid)

The sendMails method will access the passed entity selections as references. The complete code has been provided in this blog post.

Did you notice anything? The entity selections are passed “as is” to the worker. They’re ready to be shared.

The next step: new web sessions

The next step is to enhance your web applications with powerful session management designed for scalability.

In a future release, 4D web sessions will be able to handle several processes (i.e. requests) from the same user agent, at the same time. Not only will this improve performance, but it’ll provide the great benefit of sharing information between processes.

And that’s not all! You’ll be able to manage custom authentication by assigning information to your web session.

let’s discuss a use case

Imagine a global company (Acme Corp.) selling computers around the world to various customers (companies, people, schools, etc.) through a CRM application.

Each salesperson manages their own client portfolio. They’re connected to the application all day to make and register deals in their client portfolio.

We can assume the database contains at least 2 linked dataclasses: Customers and SalesPersons (a salesperson has several customers).

In the picture below, we can see that:

  • Acme Corp.’s top 10 customers are stored in Storage, thus it’s shared between all of the processes running in the application
  • Each salesperson has their own session with their top 10 customers stored in it
  • Salespeople can navigate through each page of the application and have their top 10 customers displayed, as well as Acme Corp.’s top 10 customers


These “top 10” are Customer entity selections shared either in Storage or in the user’s session.

It then becomes very easy to develop ways to:

  • test if a salesperson is a good performer (i.e., is there an intersection between their top 10 customers and Acme Corp.’s top 10 customers?)
  • refresh the salesperson’s top 10 customers
  • etc.






more concretely in 4D code

Acme Corp.’s top 10 customers are Customers entity selections put in Storage, at least at database startup:

Use (Storage)
Storage.acmeCorpTop10:=ds.Customers.all().orderBy("totalPurchase desc").slice(0; 10)
End use

The web session is nothing other than …  an object: the Session object. This object contains a shared object (storage attribute) so that all of the requests handled by the session can share data.

When the salesperson authenticates themselves, it’s very easy to store their top 10 customers with some code like:

// $salesID is the salesperson's ID
// Get the salesperson's top 10 customers
$top10:=ds.Customers.query("salesPerson.salesID = :1"; $salesID).orderBy("totalPurchase desc").slice(0; 10)
// Put $top10 in the session
Use ($userTop10
End use

Note: The code example above is a preview of a future version of 4D.

Then all the processes (i.e., requests) coming from the user agent can access these top 10 customers.

Note that you put the entity selections “as is” in Storage and in the session. There’s no need to copy them as shareable!

This is possible because entity selections are shareable by default.


in conclusion

We’ve chosen to give an advantage to all of the future use cases related to scalability and performance which should be the main issues of your future applications. A happy end user is an one who gets the right result in the shortest time.

Be aware that the purpose of a shareable entity selection is to be handled as a reference. It’s lighter in memory.

Moreover, some transparent optimizations are handled by 4D for you when you use shareable entity selections: while copying entity selections, if you ask for a shareable result, whenever applicable, 4D doesn’t make a copy of the entity selections but returns the same reference.

Thanks to all of this, you avoid copying your entity selections as shared each time you want to share them. We think these times will be too abundant as we go more and more towards code running in preemptive mode thanks to the continual progress of multiple-core processors.


• Product Owner • Marie-Sophie Landrieu-Yvert has joined the 4D Product team as a Product Owner in 2017. As a Product Owner, she is in charge of writing the user stories then translating it to functional specifications. Her role is also to make sure that the feature implementation delivered is meeting the customer need.Marie-Sophie graduated from the ESIGELEC Engineering School and began her career as an engineer at IBM in 1995. She participated on various projects (maintenance or build projects) and worked as a Cobol developer. Then she worked as an UML designer and Java developer. Lately her main roles were analyzing and writing functional requirements, coordinate business and development teams.