Several months ago, we proudly introduced ORDA and all its new concepts.
You learned that in ORDA, EVERYTHING is an object:
- the database itself is an object (the datastore object)
- each table is a dataclass object
- each record can be an entity object
- a current selection can be an entity selection 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
//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
more concretely in 4D code
Acme Corp.’s top 10 customers are Customers entity selections put in Storage, at least at database startup:
Storage.acmeCorpTop10:=ds.Customers.all().orderBy("totalPurchase desc").slice(0; 10)
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
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.
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.