Domino 9 und frühere Versionen > ND7: Entwicklung

Bug - Agent execution time?

<< < (3/4) > >>

Thomas Schulte:
Und noch eine Ergänzung: Wenn du von DB1 in DB2 eine Mail schickst, dann machst du einen Umweg. Das Dokument direkt in DB2 erstellen ist schneller und sinnvoller.

Demian:
Ich antworte euch auf die Beiträge wenn ich nachher Feierabend habe. Da kann ich in Ruhe schreiben. Hier werd ich durch meinen eigentlichen Job als rausgerissen :-\

Demian:
also dann erstmal zu euren Beiträgen:


--- Zitat ---"Sofort" ist beim Domino immer "sowie er Zeit hat".
--- Ende Zitat ---
Dessen bin ich mir bewusst und hatte mich gefreut das eben mit diesem Trigger vermeintlich ausgehebelt zu haben.


--- Zitat ---NICHT auf unprocessed documents gehen
--- Ende Zitat ---
.UnprocessedDocuments habe ich bisher eigentlich nur in Zusammenhang mit manuell markierten Dokumenten verwendet.  


--- Zitat ---Wenn du von DB1 in DB2 eine Mail schickst
--- Ende Zitat ---
Hintergrund war der Agent-Trigger. Näheres dann gleich.

Also ich versuche mal mein Konzept (wenn man es denn so nennen kann) zu beschreiben:

Mein Grundgedanke war, die Änderungen, die sich auf andere Dokumente/Datenbanken auswirken zentral an einer Stelle zu warten. Hierzu habe ich ein Extra-Template, welches nur global gültige Designelemente enthalten soll, die dann entsprechend in die eigentlichen Templates meiner Datenbanken kopiert und bei künftigen Gestaltungsänderungen aktualisiert werden.
 
Die Templates an sich versuche ich auch weitgehend identisch aufzubauen. Ich verwende z.B. für jede Maske eine eigene Lib, die die grundlegenden Maskenereignisse, sowie diverse Zusatzfunktionen beeinhaltet. Fast alle meine Masken-Libs sind wie auf dem Screenshot aufgebaut und vom Code bis auf z.B. Feldnamen grundlegend identisch.

Im _Postopen speicher ich die aktuellen Werte, um diese im _Postsave zu vergleichen. Wurde ein Wert geändert wird im _Postsave zunächst _Archived und dann _TempDocCreated aufgerufen. _TempDocCreated macht im Prinzip nichts anderes als ein Änderungsdokument mit den alten und neuen Werten zu erstellen, dieses mit dem Namen der geänderten Maske, sowie dem Namen des Users zu versehen und dann einen Agenten per .RunOnServer und der ID des Änderungsdokuments loszutreten.

Dieser Agent ist für alle Datenbanken gleich (und schön kompakt) und liegt deswegen in oben genannten Extra-Template.

Er entscheidet anhand des Maskennamens an welche Datenbank/en die Änderung weitergegeben werden muss und verschickt entsprechend das Änderungsdokument per Mail an ein oder mehrere Datenbanken. Nach Verschicken der Mail/s wird das Änderungsdokument gelöscht.

In der Empfänger-DB läuft dann der Agent mit dem Trigger vor Eingang neuer Mail an und entscheidet anhand des Maskennamens welche Änderung (z.B. oben stehendes City_EditAllHits) losgetreten wird. Nach Verarbeitung wird die Mail gelöscht.

Auch dieser Agent ist für alle DB's gleich und löste zusammen mit dem aufrufenden Agenten damals für mich viele Probleme auf einmal ohne programmatischen Mehraufwand:

- Die User sind nur bis zum Verschicken der Mail an der Verarbeitung beteiligt. Zuvor hatte ich Änderungen dieser Art immer in den jeweiligen Masken-Libs ausgeführt und der User musste so Lange warten, bis alles verarbeitet war.  
- Die Maskenlibs sind nahezu identisch aufgebaut und dadurch erheblich übersichtlicher und einfacher zu warten.
- Die Änderungen werden sofort ausgeführt (so lange der Router läuft... ::)).
- Die Agenten sind übersichtlich und schnell (näheres weiter unten).
- All meine Änderungen aus allen DB's, die sich auf andere Docs/DB's auswirken stehen an zentraler Stelle in 2 Agenten.

Wenn ich über eine Ansicht und den Trigger "nachdem Dokumente erstellt..." gehen würde (darüber habe ich damals auch nachgedacht) muss ich alle "Anforderungen" in einer Schleife durchlaufen, die dann wiederum die Schleife in z.B. oben stehenden Code auslöst.

Angenommen an Position 1 der Ansicht ist ein Änderungsdokument für den Ort Frankfurt, an Position 2 eins für den Ort Hamburg, an Position 3 eins für die Auftragsnummer XYZ und an Position 4 wieder eins für den Ort Frankfurt. Für Frankfurt müsste der eine Agent ja dann 2x alle betroffenen Dokumente in einem Lauf verarbeiten. Außerdem noch die Änderungen für den Ort Hamburg und der Auftragsnummer XYZ.

Je nach Anzahl der vorhandenen Änderungsdokumente + Anzahl der betroffenen Dokumente dürfte dieser Agent auf diese Art einiges zu tun haben. Er würde ja dann nicht nur eine Änderung für eine Maskenart verarbeiten, sondern alle Änderungen für alle Maskenarten. Das beeinhaltet zum Beispiel auch das Verschicken von Mails usw.

Der Höchstwert der betroffenen Dokumente die mein Agent in den letzten 1,5 Jahren in einem Lauf zu verarbeiten hatte, war jetzt 730 (siehe oben). Ansonsten sind es auch schonmal um die 100 Dokumente oder auch nur 1. Bei einer Änderung einer Maskenart.

So und wer jetzt nicht eingeschlafen oder total verwirrt ist, darf mich verbal verhauen ;D

Edit: Anhang fehlte.

koehlerbv:
Design - Libs -Masken -User - Massendatenveränderung .... Bahnhof!

Bitte, bitte, Demian: Trenne die Themengebiete. Ich kann mir nicht vorstellen, dass Dein Thema jetzt mit der Verteilung von Designelementen im Zusammenhang mit Änderungen von Daten in anderen Datenbanken basierend auf Datenänderungen in einer initiierenden Datenbank zu tun hat.

- Was ist das auslösende Ereignis?
- Was soll dann geändert werden?
- Wo soll das geändert werden?

Ich habe Deine Datenbanken ja gesehen (und bin damals auch durchgestiegen), aber jetzt verstehe ich - wie gesagt - nur noch Bahnhof. Ich ich helfe gerne weiter!

Bernhard

Peter Klett:
Warum bildest Du nicht alles in einem zentralen Agenten ab?

Verstanden habe ich folgendes:

Es gibt einen zentralen Agenten in einer zentralen Datenbank. Dieser Agent erhält Aufträge, aufgrund derer er Mails an die betroffenen Datenbanken sendet. In diesen betroffenen Datenbanken ist wiederum ein Agent, der die vom vorigen Agenten erstellten Aufträge abarbeitet.

Du hast also für jede Datenbank einschließlich der zentralen einen Agenten, der aktiviert und überwacht werden muss. Spätestens dann, wenn Du mehr Datenbanken hast, als zeitgleich Agenten laufen dürfen, bekommst Du einen Stau.

Da der erste Agent 1. weiß, an welche Datenbanken er welche Änderungen versenden soll, und 2. alle Routinen in der zentralen Datenbank vorliegen hat, die er zum Bearbeiten der Dokumente in den Datenbanken benötigt, könnte er die Änderung doch gleich selbst ausführen. Du bräuchtest dazu Deine Routinen vermutlich nur so anzupassen, dass die Änderungen nicht in der CurrentDatabase durchgeführt werden, sondern definierbar ist, welche Datenbank die Grundlage des Handelns ist.

Die Sorge, dass der Agent zuviel zu tun hat, sehe ich nicht. Nur durch eine Umstellung des Konzeptes werden doch die Anzahl der durchzuführenden Änderungen nicht mehr. In Deinem Beispiel muss Frankfurt auf jeden Fall zweimal geändert werden, ob zweimal durch einen Agentenlauf oder jeweils einmal bei zwei Agentenläufen. Auch Dein Agent würde damit nicht wesentlich komplizierter, evtl. musst Du nur das Initialize des Agenten in eine eigene Funktion packen, etwa so:

Set doc = col.GetFirstDocument
Do While Not doc Is Nothing
   Call MacheWasDerAgentNurEinmalTat  (doc)
   Set doc = col.GetNextDocument (doc)
Loop

Falls Du dann noch befürchtest, dass der Agent durch die zu lange Laufzeit vom AMgr abgewürgt wird, beende ihn gezielt selbst. Ich habe einen ähnlichen Agenten, der per Mail (i.d.R. Nachts) Dateien entgegennimmt und importiert. Wenn alle Lieferanten gleichzeitig liefern würden, wären das schon mal 1.000 Dateien am Stück (die senden zwar mit unterschiedlichen Zeiten, aber wenn z.B. mal wieder die Replikation zwischen dem MailServer und dem Anwendungsserver hängt - was NIE vorkommt - dann stehen alle Aufträge zeitgleich - gerne auch tagsüber -  auf der Liste). Die Agentenlaufzeitbegrenzung würde also wenigstens einen Import pro Agentenlauf stören. Deshalb ist der Agent so gebaut, dass er alle 10 Minuten startet. Zu Beginn errechnet er sich eine Stoppzeit (jetzt + 8 Minuten). Vor Verarbeitung der nächsten Datei prüft er, ob die Stoppzeit erreicht wurde. Wenn ja, beendet sich der Agent selbst und wird kurz darauf wieder neu gestartet. Es gibt dann zwar immer eine Lücke von etwa 2 Minuten, in der der Agent nichts macht, aber er ist noch nie abgewürgt worden. Und das ganze läuft schon seit 5 Jahren.

Und ich habe alles zentral in dieser einen Datenbank, auch wenn die Anzahl der betroffenen Datenbanken sich seit Beginn deutlich erhöht hat.

Navigation

[0] Themen-Index

[#] Nächste Seite

[*] Vorherige Sete

Zur normalen Ansicht wechseln