Eine der größten Veränderungen in Mendix 7 war die Einführung der zustandslosen Laufzeit, bei der der Zustand von der Laufzeit zum Client verschoben wurde. In Mendix 7 verfolgt der Client nun den Status und sendet ihn zusammen mit den Anforderungen für Browser und mobile App an die Laufzeitumgebung. Diese Funktion ermöglicht eine horizontale Skalierung der Laufzeitumgebung und bietet enorme Flexibilität, wenn eine Anwendung mehr Serverressourcen benötigt.
Im ersten Teil dieser Blogserie gehen wir eine App durch, um Ihnen zu zeigen, was aus Statusperspektive bei jedem Schritt passiert, damit Sie ein besseres Verständnis davon bekommen, wie der Clientstatus funktioniert.
Haftungsausschluss: Dieser Blogbeitrag gilt für Mendix 7.23.1. Das Statusverhalten kann in früheren Versionen abweichen und kann in zukünftigen Versionen ohne Vorankündigung geändert werden.
Was ist der Staat und was beinhaltet er eigentlich?
Als Nutzer einer Mendix app sind einige der Daten, mit denen Sie arbeiten, möglicherweise noch nicht in der Datenbank gespeichert. Genauer gesagt besteht der Status aus:
- Alle neu erstellten und noch nicht festgeschriebenen persistenten Objekte (PEs)
- Alle nicht persistenten Objekte (NPEs)
- Alle an den Objekten vorgenommenen Attribut- und Assoziationsänderungen (Assoziationen und Attribute werden im Client gleich behandelt, daher werden Assoziationen im weiteren Verlauf dieses Beitrags nicht mehr erwähnt)
Diese Objekte und Änderungen bilden den Status. Da sie noch nicht in der Datenbank Ihrer App gespeichert sind, müssen Sie sie im Status speichern, bis sie in der Datenbank gespeichert, verworfen oder in der App nicht mehr benötigt werden.
Änderungen am Zustand können auf unterschiedliche Weise vorgenommen werden:
- Ein neues Objekt kann durch einen Mikroflow in der Laufzeit, einen Nanoflow im Client oder durch eine Client-Aktion „Objekt erstellen“ erstellt werden.
- Eine Attributänderung kann durch einen Mikroflow, Nanoflow, ein benutzerdefiniertes Widget oder durch den Endbenutzer vorgenommen werden.
Aus Sicht des Status spielt die Quelle des Objekts oder der Änderung keine Rolle. Alle Objekte und Änderungen landen im Clientstatus.
Der Status kann mehr Objekte enthalten als zuvor angegeben. Manchmal enthält der Status sogar festgeschriebene Objekte. Dies wird häufig getan, um die Leistung einer App zu verbessern.
Was ist eine Änderung und wie wird sie im Status gespeichert?
Änderungen beziehen sich auf die nicht festgeschriebenen Werte von Mendix Objektattribute. Wenn ein Benutzer beispielsweise den Wert eines Attributs mithilfe eines Textfelds ändert, Mendix speichert den neuen Wert als Änderung des Zustands des bearbeiteten Objekts. Die Mendix Das Objekt selbst ist noch nicht verändert.
Die Änderungen getrennt halten von Mendix Objekte machen Rollbacks möglich. Wann immer Sie ein Rollback durchführen, Mendix Objekt in einem Microflow, Nanoflow oder mit einer Client-Aktion „Änderungen abbrechen“, Mendix verwirft einfach alle Änderungen, die für das Objekt im Status vorgenommen wurden.
Das bedeutet, dass jedes Mal, wenn ein Benutzer auf eine Schaltfläche „Speichern“ klickt, Mendix sammelt und sendet alle am bearbeiteten Objekt vorgenommenen Änderungen, damit diese Änderungen in der Datenbank der Laufzeit gespeichert werden können. Dies gilt auch für andere Laufzeitanforderungen, die ein geändertes Objekt erfordern, z. B. Mikroflow-Aufrufe.
Umfang des Staates
Mit Mendix 7, der Zustand wird im Speicher eines Browsers gespeichert durch den Mendix Client. Das bedeutet, dass der Status bei Web-Apps lokal auf den aktuellen Browser-Tab beschränkt ist. Wenn Sie Ihre App in einem separaten Tab öffnen, können Sie nicht auf den Status des vorherigen Tabs zugreifen. Das bedeutet auch, dass der Status des aktuellen Browser-Tabs verloren geht, wenn Sie ihn aktualisieren.
Es gibt eine Ausnahme zum letzten Fall. Mendix Der Client speichert Ihren Status im Sitzungsspeicher des Browsers für unsere Schnellbereitstellungsfunktion kurzzeitig. So können Sie in Ihrer App von der Seite oder dem Status aus weiterarbeiten, in dem Sie sich befanden, als Sie Änderungen an Ihrem Modell vorgenommen haben, und es dann ausführen. Diese Funktion ist nur während der Entwicklung verfügbar.
Beide oben genannten Verhaltensweisen sind neu für Mendix 7 und sind nicht kompatibel mit integrierten Apps Mendix 6 und früher. In Mendix 6. Der Status ist weiterhin von verschiedenen Registerkarten aus zugänglich und bleibt auch nach Aktualisierungen erhalten.
Staat und Sicherheit
Das Speichern des Status auf dem Client hat einige Auswirkungen auf die Sicherheit:
Schreibgeschützte Attribute für den aktuellen Benutzer- Mendix schützt schreibgeschützte Attributwerte für einen aktuellen Benutzer mit einem Hash neben diesen Werten, sodass jeder Versuch, diese Werte unrechtmäßig zu ändern, abgefangen und abgelehnt wird.
Änderungen für nicht zugängliche Attribute für den aktuellen Benutzer- Änderungen an Attributen, auf die der angemeldete Benutzer keinen Zugriff hat, können nicht im Status gespeichert werden. Beim Senden an den Client besteht die Gefahr, dass vertrauliche Daten preisgegeben werden. Daher werden solche Änderungen verworfen.
Wie wird der Status der Laufzeit mitgeteilt?
Der Mendix Der Client kommuniziert mit der Laufzeit über einen speziellen Endpunkt /xas, beispielsweise beim Laden von Daten für ein Datenraster oder beim Aufrufen eines Mikroflusses. Jeder Aufruftyp dieser API wird als Aktion bezeichnet und die erforderlichen Teile des Status werden mitgesendet. Sie können überprüfen xas Anfragen in der Netzwerk Registerkarte der Entwicklertools Ihres Browsers und Filtern von Anfragen an die xas Weg. Wir werden besuchen xas API später im Beitrag.
Haftungsausschluss: xas ist eine private API zwischen dem Mendix Client und Laufzeit und können in zukünftigen Versionen ohne Vorankündigung geändert werden. Die hier bereitgestellten Details sollen das Verständnis dafür verbessern, wie Mendix Apps kommunizieren mit der Laufzeit, sodass Sie bessere Apps modellieren und App-Probleme effektiver beheben können.
Wann immer a xas eine Aktion (z. B. ein Microflow-Aufruf) ausgelöst wird, Mendix Der Client sendet auch den Status. Mendix Der Client sendet nicht den gesamten Status an die Laufzeit, da dies zu erheblichen Leistungsproblemen führen würde. Mendix entscheidet, welche Teile des Status gesendet werden sollen, indem während der Bereitstellung der Anwendungen jeder Mikrofluss analysiert wird.
Kann ich den Clientstatus überprüfen?
Durch Drücken der Ctrl+Andere+G Tastenkombination gibt eine Zusammenfassung des Clientstatus in die Browserkonsole aus, sodass Sie prüfen können, was gespeichert ist. Wir werden diese Tastenkombination verwenden, um unsere Beispiel-App zu prüfen.
Die Kunstwerke-Registratur-App
Um den Client-Status zu demonstrieren, habe ich eine einfache Kunstwerk-Registrierungs-App erstellt, in der Informationen über Künstler gespeichert werden können.
Sie können das Projekt herunterladen werden auf dieser Seite erläutert und überprüfen Sie den Zustand, während wir ihn durchlaufen.
Hier ist unser einfaches Domänenmodell. Es gibt eine Künstler Unternehmen mit einer Vollständiger Name Attribut.
Lassen Sie uns unsere App ausführen. Die Startseite ist absichtlich leer, damit die Mendix Der Client startet mit einem leeren Zustand.

Wir können dies überprüfen, indem wir öffnen Console in Entwicklertools und durch Drücken der Strg + Alt + G. Abkürzung.

Hier sieht man, dass der Status als JSON-Objekt dargestellt wird, aktuell aber leer ist.
Klicken Sie auf die Künstler Menüpunkt. Hier gibt es eine Listenansicht aller in der App definierten Künstler. Aktuell sind keine vorhanden.

Erstellen Sie einen neuen Künstler, indem Sie auf das Neuen Künstler erstellen und prüfen Sie, was passiert in der Netzwerk Registerkarte der Entwicklertools. Wählen Sie die erste Anfrage an den xas/ Pfad und scrollen Sie nach unten auf dem Headers Registerkarte in der Detailansicht:

Extrahieren Sie die Anforderungsnutzlast und überprüfen Sie:
Switch to "Text" tab and paste code here
Oben sehen Sie ein typisches xas Anfrage. Lassen Sie uns jedes Feld durchgehen:
action: Wir haben erwähnt, dass alle Laufzeitoperationen einenxasAPI, daher muss jede Operation unterscheidbar sein. Hier dieactionFeld dient diesem Zweck. Die aktuelle Aktion istinstantiate, die die Laufzeit auffordert, eine Mendix Objekt.params: JederxasAktion kann einen eigenen Parametersatz haben, soparamsenthalten die aktionsspezifischen Parameter. Für eineinstantiateAufruf muss die Laufzeitumgebung wissen, welcher Objekttyp erstellt werden soll, daher wird dieser imobjecttypeFeld.changes: Dies ist eines der Felder, die sich auf den Clientstatus beziehen. Immer wenn einxasAnfrage gestellt wird, Mendix Der Client sendet den entsprechenden Status mit der Anfrage undchangesist ein Teil dieses Status. Da zum Erstellen eines neuen Objekts kein Status erforderlich ist, ist es hier leer.objects: Dies ist das zweite Feld, das sich auf den Clientstatus bezieht. Hier die Mendix Der Client liefert Objekte aus dem Zustand, den die Laufzeit während der Anforderung möglicherweise benötigt. Da zum Erstellen eines neuen Objekts kein Objektzustand erforderlich ist, ist es auch leer.
Überprüfen Sie die Antwort durch Auswahl des Vorschau Registerkarte innerhalb der Netzwerk Detailansicht anfordern:

Bei der Untersuchung der Details werde ich auf die Screenshots der Entwicklertools verzichten und nur die extrahierten Versionen zeigen:
{
"actionResult": "5629499534213124",
"commits": [],
"changes": {},
"resets": {},
"deletes": [],
"newpersistable": [
"5629499534213124"
],
"objects": [
{
"objectType": "MyFirstModule.Artist",
"guid": "5629499534213124",
"hash": "Nw09VTjCQKib7DbE5Agxgm3Bg6fEGL4mPRyNrgiUKGs=",
"attributes": {
"FullName": {
"value": null
}
}
}
]
}
Oben sehen Sie ein typisches xas Antwort. Die actionResult Das Feld ist direkt mit der Aktion selbst verknüpft, die anderen Felder beziehen sich jedoch auf den Clientstatus.
Nach jedem Anruf beim xas, die Laufzeitantwort enthält Informationen darüber, was während der Anfrage passiert ist, z. B. welche Objekte erstellt oder gelöscht wurden. Die Laufzeit kommuniziert diese in jeder Antwort an den Client, sodass der Client diese Änderungen auf seinen Status anwendet.
Hier ist eine Übersicht über die Antwortfelder im Zusammenhang mit dem Clientstatus:
Commits
Dieses Feld enthält eine Liste der GUIDs, die während der Anfrage übermittelt wurden. Da das Erstellen selbst das Objekt nicht übermittelt, ist es leer. Wenn es ausgefüllt ist, sieht es folgendermaßen aus:
"commits": ["guid_1", "guid_2", "...guid_n"]
Der Mendix Der Client verwendet diese Informationen, um zu wissen, wann ein neues Objekt festgeschrieben wurde oder nicht. Auf diese Weise kann er den Clientstatus entsprechend aktualisieren.
Änderungen
Dieses Feld enthält eine Zusammenfassung aller Änderungen an der Mendix Objekte, die während der Anfrage vorgenommen wurden. Das bedeutet, dass diese Änderungen noch nicht festgeschrieben wurden und daher im Status gespeichert werden sollten.
Dieses Feld ist nicht ausgefüllt in instantiate Aufruf, da es keine Änderungen für die neue Artist Objekt noch nicht. Aber wenn die Artist Das Objekt hätte einen Mikrofluss des Ereignisses „Nach dem Erstellen“ gehabt, der den Namen des Künstlers in einen Standardwert geändert hätte. Dieses Feld hätte folgendermaßen ausgesehen:
"changes": {
"5629499534213124": {
"FullName": {
"value": "Value set in the event microflow"
}
}
}
Der Mendix Der Client nimmt hier Änderungen vor und wendet sie auf den Client-Status an.
Zurücksetzen
Dieses Feld enthält eine Zusammenfassung aller zurückgesetzten Attributänderungen für jeden Mendix Objekt. Mendix Der Client verwendet diese Informationen, um die vorhandenen Änderungen aus seinem Status zu entfernen. Hier ist ein Beispiel dafür, wie Zurücksetzungen aussehen:
"resets": {
"guid_of_the_object": ["attribute_1", "attribute_2"]
}
Löscht
Dieses Feld enthält eine Liste von GUIDs von Mendix Objekte, die während der Anfrage gelöscht wurden. Die Mendix Der Client verwendet diese Löschinformationen, um entsprechende Objekte und ihre Änderungen aus dem Status zu entfernen. Dieses Feld ist in der obigen Beispielanforderung leer, aber hier ist ein Beispiel dafür, wie Löschungen aussehen:
"deletes": ["guid_1", "guid_2", "...guid_n"]
Neubeständig
Dieses Feld enthält eine Liste der GUIDs, die während der Anfrage erstellt wurden. Mendix Der Client weiß, dass sie noch nicht festgeschrieben sind, und muss sie so lange wie nötig speichern. In unserem instantiate Anruf, es erstellte eine neue Artist Objekt, aber nicht festgeschrieben. Deshalb sehen wir, dass seine GUID Teil dieses Felds ist.
Objekte
Dieses Feld enthält eine Liste von Mendix Objekte, die die Laufzeitaktion als Teil der Antwort an den Client senden muss. In unserem Beispiel sendet die Laufzeit die JSON-Darstellung des neuen Artist Objekt.
Ein typischer Mendix Das Objekt kann die folgenden Felder haben:
objectType: definiert den Objekttyp des Objekts.guid: eindeutige ID des Objekts.hash: Dadurch wird sichergestellt, dass der gesamte Objektinhalt nicht manipuliert wird.attributes: enthält die begangen Werte für jedes Attribut des Objekts. Bei einem neuen Objekt entsprechen diese Werte den Standardwerten der Attribute. Bitte beachten Sie, dass nur die Attribute vorhanden sind, auf die der aktuelle Benutzer zugreifen kann.
Kehren wir nach dieser kurzen Einführung zu unserer Demoanwendung zurück xas Anfrage und Antwort.
Durch Klicken auf die Schaltfläche „Neu“ wird eine neue Instanz der Entität „Künstler“ erstellt, und die Mendix Client zeigt die Detailseite mit dem neuen Objekt:

Hier können wir nun unsere Statusinspektionsverknüpfung verwenden (Ctrl+Andere+G), um den Clientstatus anzuzeigen:
{
"MyFirstModule.Artist": {
"5629499534213124 (new)": {
"subscribedWidgets": [
"MyFirstModule.Artist_NewEdit.dataView1",
"MyFirstModule.Artist_NewEdit.textBox1",
null
]
}
}
}
Der Klientelstaat hat nun die neue Mendix Objekt, und stellt es dar, indem es ein (new) Präfix nach seiner GUID, um anzuzeigen, dass es noch nicht festgeschrieben wurde. Es hat auch eine subscribedWidgets Feld, das die Widgets angibt, die dieses Objekt verwenden. Deshalb wird dieses Objekt im Status gehalten. Der letzte Eintrag ist null, was bedeutet, dass sich auf der Seite oder im Mendix Client selbst, der das Objekt verwendet, aber keine Beschreibung hat.
Ändern Sie den Namen des neuen Künstlers in Pablo Picasso, und überprüfen Sie dann den Status erneut:
{
"MyFirstModule.Artist": {
"5629499534213124 (new)": {
"changes": {
"FullName": {
"value": "Pablo Picasso"
}
},
"subscribedWidgets": [
"MyFirstModule.Artist_NewEdit.dataView1",
"MyFirstModule.Artist_NewEdit.textBox1",
null
]
}
}
}
}
Dieses Mal sehen wir, dass es ein Extra gibt changes Feld für das Objekt, in dem die Änderung angezeigt wird, die wir am FullName Feld.
In diesem Moment, Mendix Der Client speichert sowohl den ursprünglichen als auch den geänderten Wert des FullName Feld. Sie können dies überprüfen, indem Sie das Objekt von der Konsole aus anfordern mit mx.data.get und Vergleichen der zurückgegebenen Werte von MxObject.get und MxObject.getOriginalValue Methoden:

Speichern Sie diesen Künstler durch Klicken auf das Save und überprüfen Sie die dadurch ausgelöste Anfrage (einige Felder wurden der Übersichtlichkeit halber weggelassen):
{
"action": "commit",
"params": {
"guids": [
"5629499534213124"
]
},
"changes": {
"5629499534213124": {
"FullName": {
"value": "Pablo Picasso"
}
}
},
"objects": [{
"objectType": "MyFirstModule.Artist",
"guid": "5629499534213124",
"hash": "31doiDAq6u7/rMnqwWno01jhLkhpeQ+vKU/rI+IQor8=",
"attributes": {
"FullName": {
"value": null
}
}
}]
}
Diesmal a commit Aktionsanforderung an die Laufzeit gesendet, die die guid des zu übertragenden Objekts in der params Feld. Auch die changes Feld enthält die Pablo Picasso Änderung, die wir vorgenommen haben, und objects enthält das Mendix Objekt, das wir zuvor erstellt haben.
Hier ist die Antwort:
{
"commits": [
"5629499534213124"
],
"changes": {},
"resets": {
"5629499534213124": [
"FullName"
]
},
"deletes": [],
"newpersistable": [],
"objects": [{
"objectType": "MyFirstModule.Artist",
"guid": "5629499534213124",
"hash": "31doiDAq6u7/rMnqwWno01jhLkhpeQ+vKU/rI+IQor8=",
"attributes": {
"FullName": {
"value": "Pablo Picasso"
}
}
}]
}
Es gibt keine actionResult Feld dieses Mal, aber es gibt viele Änderungen für den Staat:
- Der
commitsenthält nun dieguidArtistwir haben gerade ein Commit durchgeführt, daher weiß der Client-Status, dass es sich nicht mehr um ein neues Objekt handelt. - Der
resetsFeld enthält dieguidArtistund erwähnt, dassFullNameDie Feldänderung wird entfernt (da sie nun festgeschrieben ist). Der Client kann diese Änderung nun aus dem Status entfernen.
Der objects stellt nun die neueste Version des festgeschriebenen Objekts dar, wobei die FullName Feldwert gesetzt auf Pablo Picasso.
Warum gibt die Laufzeit das festgeschriebene Objekt erneut zurück?
Der Client hat das Objekt bereits in seinem Zustand und könnte es wiederverwenden. Warum gibt die Laufzeit es also erneut zurück? Dafür gibt es zwei Gründe:
- Das Objekt verfügt möglicherweise über einen Eventhandler, der das Objekt weiter modifiziert hat
- Das Objekt verfügt möglicherweise über ein berechnetes Attribut und sein Wert hat sich möglicherweise geändert, als es festgeschrieben wurde.
Aus diesem Grund benötigt der Client die neuesten Werte des Objekts und deshalb werden diese von der Laufzeit zurückgegeben.
Jetzt sieht Ihre Anwendung folgendermaßen aus:

Wenn Sie den Staat jetzt untersuchen, werden Sie sehen, dass Pablo Picasso befindet sich noch im Status, da es von der Listenansicht verwendet wird. Es gibt jedoch einen kleinen Unterschied: Es ist nicht mehr als neu markiert.
{
"5629499534213124": {
"subscribedWidgets": [
"MyFirstModule.Artist_Overview.listView1",
"MyFirstModule.Artist_Overview.textBox1"
]
}
}
Der Mendix Der Client verwendet den Clientstatus auch als eine Art Caching-Ebene. Wenn sich ein Objekt im Status befindet und von einem Widget benötigt wird, wird es nicht erneut von der Laufzeit abgerufen. Klicken Sie auf das Künstler bearbeiten Klicken Sie auf „Pablo Picasso“ und überprüfen Sie die Netzwerk Registerkarte devtools. Sie werden feststellen, dass keine neuen xas Es werden Anfragen gestellt, um Pablo Picasso von der Laufzeit. Da es sich bereits im Status befindet, muss es nicht angefordert werden.
Klicken wir nun Abbrechen Gehen Sie auf der Bearbeitungsseite zur Startseite unserer Anwendung, indem Sie auf Startseite und überprüfen Sie den Status:
{
"MyFirstModule.Artist": {
"5629499534213124": "Going to be garbage collected †"
}
}
Überprüfen Sie den Status etwa 15 Sekunden später. Sie werden sehen, dass er leer ist.
Aber warum ist das so?
Die Antwort auf diese Frage liegt in einem neuen Konzept: Garbage Collection aus dem Status. Dieser Mechanismus erkennt und entfernt unnötige Objekte aus dem Status, sodass unsere Anwendung unabhängig von der Anzahl der erstellten oder verwendeten Objekte optimal funktioniert. In unserer Anwendung Pablo Picasso Das Objekt wird nicht mehr benötigt, da wir die Startseite geöffnet haben, da es keine Widgets gibt, die es anzeigen. Deshalb wird es aus dem Status entfernt. Die Garbage Collection aus dem Status ist jedoch ein komplexes Thema, daher werde ich es im zweiten Teil dieser Blogserie behandeln.
Ich hoffe, Ihnen hat das Lesen dieses Beitrags gefallen und Sie finden ihn hilfreich. Bis später zu Teil 2!
