Utiliser un datastore distant
A datastore exposed on a 4D application can be accessed simultaneously through different clients:
- 4D remote applications using ORDA to access the main datastore with the
dscommand. A noter que l'application 4D distante peut toujours accéder à la base de données en mode classique. These accesses are handled by the 4D application server. - Other 4D applications (4D remote, 4D Server) opening a session on the remote datastore through the
Open datastorecommand. These accesses are handled by the HTTP REST server. - 4D for iOS or 4D for Android queries for updating mobile applications. These accesses are handled by the HTTP server.
Ouverture des sessions
When you work with a remote datastore referenced through calls to the Open datastore command, the connection between the requesting processes and the remote datastore is handled via sessions.
Une session est créée sur le datastore distant pour gérer la connexion. This session is identified using a internal session ID which is associated to the localID on the 4D application side. Cette session gère automatiquement l'accès aux données, aux entity selections et aux entités.
Le localID est local à la machine qui se connecte au datastore distant, ce qui signifie que :
- Si d'autres process de la même application doivent accéder au même datastore distant, ils peuvent utiliser le même
localIDet partager alors la même session. - Si un autre process de la même application ouvre le même datastore distant, mais avec un autre
localID, il créera une nouvelle session sur le datastore distant. - Si un autre poste se connecte au même datastore distant avec le même
localID, il créera une autre session avec un autre cookie.
Ces principes sont illustrés dans les graphiques suivants :

For sessions opened by REST requests, please refer to Users and sessions.
Visualiser les sessions
Les process qui gèrent les sessions d'accès aux datastore apparaissent dans la fenêtre d'administration de 4D Server :
- nom : "REST Handler : <nom du process>"
- type : type Worker Server HTTP
- session : le nom de session est le nom d'utilisateur passé à la commande
Open datastore.
Dans l'exemple suivant, deux process sont en cours d'exécution pour la même session :

Verrouillage et transactions
Les fonctionnalités ORDA relatives au verrouillage d'entité et aux transactions sont gérées au niveau du process dans les datastore distants, tout comme en mode client/serveur ORDA :
- Si un process verrouille une entité à partir d'un datastore distant, l'entité est verrouillée pour tous les autres process, même lorsque ces process partagent la même session (voir Verrouillage d'entités). Si plusieurs entités pointant vers le même enregistrement ont été verrouillées dans un process, elles doivent toutes être déverrouillées dans le process pour supprimer le verrou. Si un verrou a été mis sur une entité, il est supprimé lorsqu'il n'existe plus de référence à cette entité en mémoire.
- Les transactions peuvent être lancées, validées ou annulées séparément sur chaque datastore distant à l'aide des méthodes
dataStore.startTransaction( ),dataStore.cancelTransaction( ), etdataStore.validateTransaction( ). Elles n’ont pas d’incidences sur les autres datastore. - Les commandes classiques du langage 4D (
START TRANSACTION,VALIDATE TRANSACTION,CANCEL TRANSACTION) s'appliquent uniquement au datastore principal (renvoyé pards). Si une entité d'un datastore distant est verrouillée par une transaction dans un process, les autres process ne peuvent pas la mettre à jour, même si ces process partagent la même session. - Les verrous sur les entités sont supprimés et les transactions sont annulées :
- lorsque le process est tué.
- quand la session est fermée sur le serveur
- lorsque la session est arrêtée à partir de la fenêtre d’administration du serveur.
Fermeture des sessions
Une session est automatiquement fermée par 4D lorsqu'il n'y a pas eu d'activité durant son timeout. Le timeout par défaut est de 60 mn mais cette valeur peut être paramétrée à l'aide du paramètre connectionInfo de la commande Open datastore.
Si une demande est envoyée au datastore distant après la fermeture de la session, elle est automatiquement recréée si possible (licence disponible, serveur non arrêté, etc.). A noter cependant que le contexte de la session des verrous et des transactions est perdu (voir ci-dessus).
Optimisation client/serveur
4D provides optimizations for ORDA requests that use entity selections or load entities in client/server configurations (datastore accessed remotely through ds or via Open datastore). Ces optimisations accélèrent l'exécution de votre application 4D en réduisant drastiquement le volume d'informations transmises sur le réseau. Elles incluent :
- le contexte d'optimisation
- le Cache ORDA
Contexte
Le contexte d'optimisation est fondé sur ce qui suit :
-
Lorsqu'un client requête une entity selection au serveur, 4D "apprend" automatiquement quels attributs de l'entity selection sont réellement utilisés côté client lors de l'exécution du code, et génère un "contexte d'optimisation" correspondant. Ce contexte est lié à l'entity selection et stocke les attributs utilisés. Il sera mis à jour dynamiquement si d'autres attributs sont utilisés par la suite. Les commandes et fonctions suivantes déclenchent la phase d'apprentissage :
-
Les requêtes ultérieures envoyées au serveur sur la même entity selection réutilisent automatiquement le contexte d'optimisation et lisent uniquement les attributs nécessaires depuis le serveur, ce qui accélère le traitement. Les requêtes ultérieures envoyées au serveur sur la même entity selection réutilisent automatiquement le contexte d'optimisation et lisent uniquement les attributs nécessaires depuis le serveur, ce qui accélère le traitement. L'affichage des lignes suivantes est optimisé. Les fonctions suivantes associent automatiquement le contexte d'optimisation de l'entity selection d'origine à l'entity selection retournée :
-
Un contexte d'optimisation existant peut être passé en tant que propriété à une autre entity selection de la même dataclass, ce qui permet d'éviter la phase d'apprentissage et d'accélérer l'application (voir Utilisation de la propriété context ci-dessous).
-
Vous pouvez créer des contextes d'optimisation manuellement à l'aide de la fonction
dataStore.setRemoteContextInfo()(voir Préconfiguration des contextes).

Les contextes gérés dans les connexions établies via Open datastore peuvent uniquement être utilisés entre des versions principales similaires de 4D. Par exemple, une application distante 4D 20.x ne peut utiliser que des contextes d'un datastore 4D Server 20.x.
Exemple
Considérons le code suivant :
$sel:=$ds.Employee.query("firstname = ab@")
For each($e;$sel)
$s:=$e.firstname+" "+$e.lastname+" works for "+$e.employer.name // $e.employer renvoie à la table Company
End for each
Grâce à l'optimisation, cette requête récupérera uniquement les données des attributs utilisés (firstname, lastname, employer, employer.name) dans $sel à partir de la deuxième itération de la boucle.
Réutiliser la propriété context
Vous pouvez augmenter les avantages de l'optimisation en utilisant la propriété context. Cette propriété référence un contexte d'optimisation "appris" pour une entity selection. Elle peut être passée comme paramètre aux fonctions ORDA qui retournent de nouvelles entity selections, afin que les entity selections demandent directement au serveur les attributs utilisés, sans passer par la phase d'apprentissage.
Vous pouvez également créer des contextes en utilisant la fonction
.setRemoteContextInfo().
Une même propriété de contexte d'optimisation peut être passée à un nombre illimité d"entity selections de la même dataclass. Une même propriété de contexte d'optimisation peut être passée à un nombre illimité d"entity selections de la même dataclass. Il est toutefois important de garder à l'esprit qu'un contexte est automatiquement mis à jour lorsque de nouveaux attributs sont utilisés dans d'autres parties du code. Si le même contexte est réutilisé dans différents codes, il risque d'être surchargé et de perdre en efficacité.
Un mécanisme similaire est implémenté pour les entités qui sont chargées, de sorte que seuls les attributs utilisés sont demandés (voir la fonction
dataClass.get()).
Exemple avec 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) // dans la méthode extractData un contexte d'optimisation
// est généré et associé au contexte "shortList"
$sel2:=ds.Employee.query("lastname = Sm@";$querysettings)
$data:=extractData($sel2) // dans la méthode extractData le contexte d'optimisation
// associé au contexte "shortList" est appliqué
$sel3:=ds.Employee.query("lastname = Smith";$querysettings2)
$data:=extractDetailedData($sel3) // dans la méthode extractDetailedData un contexte d'optimisation
// est généré et associé au contexte "longList"
$sel4:=ds.Employee.query("lastname = Brown";$querysettings2)
$data:=extractDetailedData($sel4) // dans extractDetailedData le contexte d'optimisation
// associé au contexte "longList" est appliqué
List box de type entity selection
L'optimisation d'entity selection s'applique automatiquement aux listbox basées sur une entity selection dans les configurations client/serveur, au moment d'afficher et de dérouler le contenu d'une listbox : seuls les attributs affichés dans la listbox sont demandés depuis le serveur.
Un contexte spécifique nommé "page mode" est également fourni lorsque l'entité courante de la sélection est chargée à l'aide de l'expression de la propriété Elément courant de la list box (voir List box de type collection ou entity selection). Cette fonctionnalité vous permet de ne pas surcharger le contexte initial de la listbox dans ce cas précis, notamment si la "page" requiert des attributs supplémentaires. A noter que seule l'utilisation de l'expression Elément courant permettra de créer/utiliser le contexte de la page (l'accès via entitySelection[index] modifiera le contexte de l'entity selection).
Les requêtes ultérieures adressées au serveur par les fonctions de navigation parmi les entités prendront également en charge cette optimisation. Les fonctions suivantes associent automatiquement le contexte d'optimisation de l'entité source à l'entité retournée :
Par exemple, le code suivant charge l'entité sélectionnée et permet de naviguer dans l'entity selection. Les entités sont chargées dans un contexte séparé et le contexte initial de la listbox demeure inchangé :
$myEntity:=Form.currentElement //expression de l'élément courant
//... faire quelque chose
$myEntity:=$myEntity.next() //charge l'entité suivante à l'aide du même contexte
Préconfiguration des contextes
Un contexte d'optimisation doit être défini pour chaque fonctionnalité ou algorithme de votre application, afin d'obtenir les meilleures performances. Par exemple, un contexte peut être utilisé pour les requêtes sur les clients, un autre contexte pour les requêtes sur les produits, etc.
Si vous souhaitez livrer des applications finales avec le plus haut niveau d'optimisation, vous pouvez préconfigurer vos contextes et ainsi économiser des phases d'apprentissage en suivant ces étapes :
- Concevez vos algorithmes.
- Exécutez votre application et laissez le mécanisme d'apprentissage automatique remplir les contextes d'optimisation.
- Appelez la fonction
dataStore.getRemoteContextInfo()oudataStore.getAllRemoteContexts()pour collecter les contextes. Vous pouvez utiliser les fonctionsentitySelection.getRemoteContextAttributes()etentity.getRemoteContextAttributes()pour analyser comment vos algorithmes utilisent les attributs. - Dans la dernière étape, appelez la fonction
dataStore.setRemoteContextInfo()pour construire des contextes au démarrage de l'application et utilisez-les dans vos algorithmes.
Cache ORDA
Pour des raisons d'optimisation, les données demandées au serveur via ORDA sont chargées dans le cache distant ORDA (qui est différent du cache 4D). Le cache ORDA est organisé par dataclass et expire au bout de 30 secondes.
Les données contenues dans le cache sont considérées comme expirées lorsque le délai d'attente est atteint. Tout accès à des données périmées provoquera l'envoi d'une requête au serveur. Les données périmées restent dans le cache jusqu'à ce que l'on ait besoin d'espace.
Par défaut, le cache ORDA est géré de manière transparente par 4D. Cependant, vous pouvez contrôler son contenu en utilisant les fonctions ORDA suivantes :