Releases: sos-berlin/js7
v2.4.0-beta.20220708
- ❗️ Journale der Versionen 2.4.0-beta-* sind nicht kompatibel und müssen gelöscht werden, wenn Suspend Workflow oder Skip Job genutzt worden ist.
- Die Informationen zu Suspend Workflow und Skip Job werden in einem (internen) Item WorkflowPathControl gehalten. Das Item soll nicht über die Item-Schnittstelle angefasst werden, nur über die zuständigen Kommandos.
- FIX: Bei ResetAgent werden auch SubagentReset-Events ausgelöst, weil die Subagenten implizit als zurückgesetzt gelten (die müssen ggfs. neu gestartet werden.)
JControllerState
:workflowPathControlToIgnorantAgent
undsingleWorkflowPathControlToIgnorantAgents
sollten jetzt schnell sein.orderToAvailableNotices
liefert die bereits vorhandenen Notizen für ExpectNoticesorderToStillExpectedNotices
liefert die noch fehlenden Notizen für die ExpectNotices-Anweisung. Dazu werden alle BoardPath des Ausdrucks herangezogen, auch wenn die Anweisung wegen einer Oder-Verknüpfung bestimmte Notizen nicht mehr braucht.
- ExpectNotices-Anweisung erlaubt Klammern im Ausdruck.
- Die Datei DATA/state/pid heißt wieder DATA/state/lock, denn sie dient in erster Linie zum Verhindern eines doppelten Starts (ab Java 9 erhält sie außerdem die PID.)
AgentRefState.platformInfo
undSubagentItemState.platformInfo
enthalten die neuePlatformInfo
mit der JS7-Versionbezeichnung und weiteren Informationen vom letzten Start des Agenten bzw. Subagenten.- Berechnung für MonthlyLastWeekdayPeriod.secondsOfWeeks geändert (siehe unten)
Berechnung für MonthlyLastWeekdayPeriod.secondsOfWeeks geändert
Der Wert ist immer negativ. Er errechnet sich aus der Anzahl Sekunden seit Montag 0:00 abzüglich 7 · 24 · 3600 für jede zurückgehende Woche, also 7 · 24 · 3600 für die letze Woche und 4 · 7 · 24 · 3600 für die viertletzte Woche.
Der größte mögliche Wert ist -1 für den letzten Sonntag des Monats um 23:59:59.
val WeekSeconds = 7 * 24 * 3600
// Last Friday
val period1 = MonthlyLastWeekdayPeriod(-1, FRIDAY, LocalTime.of(3, 0), 1.h)
assert(period1 == MonthlyLastWeekdayPeriod((4*24 + 3)*3600 - 1*WeekSeconds, 1.h))
// Second last Friday
val period = MonthlyLastWeekdayPeriod(-2, FRIDAY, LocalTime.of(3, 0), 1.h)
assert(period == MonthlyLastWeekdayPeriod((4*24 + 3)*3600 - 2*WeekSeconds, 1.h))
// Fourth last Friday
val period4 = MonthlyLastWeekdayPeriod(-4, FRIDAY, LocalTime.of(3, 0), 1.h)
assert(period4 == MonthlyLastWeekdayPeriod((4*24 + 3)*3600 - 4*WeekSeconds, 1.h))
v2.4.0-beta.20220624
- JS-1944 ControllerCommand.ControlWorkflowPath ersetzt ControlWorkflow
- JS-1944 OrderObstacle.WorkflowSuspended
- JS-1969 Skip Jobs
ControllerCommand.ControlWorkflowPath ersetzt ControlWorkflow
{
"TYPE": "ControlWorkflowPath",
"workflowPath": "WORKFLOW",
"suspend": true
}
suspend
ist jetzt optional (wegen Skip Jobs).
OrderObstacle.WorkflowSuspended
Neues Obstacle, wenn der WorkflowPath suspendiert ist.
Skip Jobs
Das ControlWorkflowPath
-Kommando kann Execute-Anweisungen überspringen lassen. Beim Übersprung kein Event wird außer OrderMoved
wird ausgegeben.
Um eine Execute-Anweisung zu überspringen, braucht sie ein Label, das im Kommando angegeben wird. Mehrere Label können an- und abgeschaltet werden.
{
"TYPE": "ControlWorkflowPath",
"workflowPath": "WORKFLOW",
"skip": {
"A-LABEL": true,
"B-LABEL": true,
"C-LABEL": false
}
}
Nur Execute-Anweisungen lassen sich überspringen. Label andererer Anweisungen werden ignoriert.
JControllerState.workflowPathControlToIgnorantAgent
liefert eine Map mit den Agenten für jeden WorkflowPath, die noch nicht den letzten Stand des WorkflowPathControls haben (also ob der Workflow suspendiert ist oder Execute-Anweisungen übersprungen werden).
JController>State.singleWorkflowPathControlToIgnorantAgents
liefert dieselbe Information für einen bestimmten WorkflowPath.
Beide Funktionen gehen sämtliche Aufträge durch und können bei sehr vielen Aufträgen einige Zehntel Sekunden brauchen.
v2.4.0-beta.20220619
JS-1972 Order.startPosition und stopPosiitions: Try, If, Label
stopPositions ist jetzt im Plural und ist eine Menge (JSON: ein Array) von Position, an denen der Auftrag stoppen soll.
startPosition und stopPositions können Positionen verschachtelt in Try- und If-Anweisungen sein. Dieselben Regeln wie bei ResumeOrder gelten. Dieselben Proxy-Methoden können verwendet werden.
Alle Positionen lassen sich wahlweise als rohe Position oder als Label angeben (in JSON als String).
{
"id": "ORDER-ID",
"workflowPath": "WORKFLOW",
"startPosition": [ 1 ],
"stopPositions": [ [ 9 ], "LABEL" ]
}
v2.4.0-beta.20220614
- Additional PermissionPeriods
- MonthlyDatePeriod
- MonthlyLastDatePeriod
- MonthlyWeekdayPeriod
- MonthlyLastWeekdayPeriod
MonthlyDatePeriod
Ein bestimmter Tag eines Monats
secondOfMonth
= number of seconds since first of month, midnight
Beispiel (JSON): Der 4. eines Monats, 03:00 Uhr, für 10 Minuten
{
"TYPE": "MonthlyDatePeriod",
"secondOfMonth": 270000,
"duration": 600
}
Wenn der Monat zu wenige Tage hat, wird der letzte Tag gewählt, bei gleicher Uhrzeit. Zum Beispiel wird als 31. Tag eines Aprils der 30. April angenommen.
MonthlyLastDatePeriod
Ein bestimmter der letzten 28 Tage eines Monats, rückwärts ab Monatsende gezählt.
secondOfMonth
= -
number of seconds since first of next month, midnight — always negative
Beispiel (JSON): Der letzte eines Monats, 23:00 Uhr, für 10 Minuten
{
"TYPE": "MonthlyLastDatePeriod",
"lastSecondOfMonth": -3600,
"duration": 600
}
MonthlyWeekdayPeriod
Ein bestimmter Wochentag in einer der ersten vier Wochen eines Monats.
Beispiel (JSON): Der zweite Donnerstag eines Monats, 3:00 Uhr, für 10 Minuten
{
"TYPE": "MonthlyWeekdayPeriod",
"secondOfWeeks": 874800,
"duration": 600
}
MonthlyLastWeekdayPeriod
Bestimmter Wochentag eines Monats in einer der letzten vier Wochen eines Monats, rückwärts ab Monatsende gezählt.
secondOfMonth
= number of seconds since last monday, midnight -
number of weeks to shift backwards
Beispiel (JSON): Der zweitletze Freitag eines Monats, 3:00 Uhr, für 10 Minuten
secondOfMonth
= 4·24·3600 + 3*3600 - 7·24·3600 = -248400
{
"TYPE": "MonthlyLastWeekdayPeriod",
"secondOfWeeks": -248400,
"duration": 600
}
v2.4.0-beta.20220609
FreshOrder.startPosition and .stopPosition
startPosition: Option[Position]
stopPosition: Option[Position]
Die Positionen müssen auf oberste Stufe sein (nicht in einem Branch). In der JSON-Darstellung hat das Array nur ein Element (die Anweisungnummer).
Der Auftrag startet an der angegebenen Position und endet, wenn der die stopPosition erreicht, als stünde da eine Finish-Anweisung.
v2.4.0-beta.20220608
ControlWorkflow command suspends a Workflow
In Java:
JControllerCommand.controlWorkflow(workflowPath, suspend: Boolean)
v2.4.0-beta.20220601
- Basiert auf v2.3.2, dem aktuellen Stand von v2.3
- JS-1954 Verbesserungen für Subagenten
- Beim Start werden die Zertifikate zur Prüfung der InventoryItem-Signaturen übersichtlicher und mit CA-Kennzeichen protokolliert.
- JS-1945
ForkList
-Anweisung liefert Ergebnisse der Kindaufträge - JS-1948
PostNotices
- undExpectNotices
-Anweisungen. - DATA/work-Verzeichnis und Start der Engine verbessert
- Corellation-IDs (
CorrelId
)
JS-1954 Verbesserungen für Subagenten
- FIX: Shutdown eines Subagenten vor Prozessstart wird erkannt. Der Prozess gilt dann als abgebrochen (und wird wiederholt).
- FIX: Weniger (keine) Fehlermeldungen, wenn ein Subagent gestorben ist.
- FIX: Weniger Warnungen, wenn ein Subagent nicht erreichbar ist.
DelegateCouplingState.Reset
hat ein Feldreason
bekommen, das den Grund aufschlüsselt:Fresh
— der initiale ZustandResetCommand
— Folge desResetAgent
oderResetSubagent
-KommandosShutdown
— der Subagent ist heruntergefahren worden (und konnte das dem Director melden, was nicht zuverlässig geschieht).Restart
— der Subagent ist erneut gestartet worden.
OrderProcessing(Outcome.Disrupted.ProcessLost)
hat ein Feldproblem
bekommen, das den Grund mit folgenden Problem-Codes aufschlüsselt:ProcessLostDueToRestart
ProcessLostDueToReset
ProcessLostDueToShutdown
ProcessLostDueSubagentUriChange
ProcessLostDueToUnknownReason
zur Kompatibilität mit v2.3
JS-1945 Die ForkList
-Anweisung liefert die Ergebnisse der Kindaufträge.
Im Unterschied zu Fork werden die Ergebnisvariablen als Listen geliefert, deren Index dem Index der Kindaufträge entspricht.
Auf ein Listenelement kann zugegriffen werden mit $list(0)
oder ${list}(0)
.
JS-1948 PostNotices und ExpectNotices
Notizen lassen sich an mehrere Boards heften und mit einem Prädikat von mehreren Boards erwarten.
Die Anweisungen PostNotices
und ExpectNotices
ersetzen die Anweisungen PostNotice
und ExpectNotice
(jedoch bleiben die zur Kompatibilität erhalten).
PostNotices
hat das FeldboardPaths
mit einer Liste der Namen mehrerer schwarzen Bretter.ExpectNotices
erwartet im FeldboardPaths
einen Ausdruck einer speziellen kleinen Ausdruckssprache, die konstante Strings für BoardPath, sowie die Operatoren&&
und||
kennt (&&
bindet stärker)."boardPaths": "'A-BOARD' || 'B-BOARD' && 'C-BOARD'"
- Die Anweisung setzt fort, sobald (zu einem Zeitpunkt) der Ausdruck erfüllt ist.
Neben den Anweisungen haben sich auch die Events geändert. Die alten Events werden noch verstanden.
DATA/work-Verzeichnis und Start der Engine
- Die Datei DATA/work/pid ersetzt DATA/state/lock und enthält ab Java 9 die PID.
- Die Datei wird weiterhin als Schutz vor doppelten Start genutzt. Sie soll nicht gelöscht oder überschrieben werden.
- Das Verzeichnis DATA/work wird beim Start (nach Prüfung auf doppelten Start) gelöscht.
- Das Verzeichnis DATA/work soll nur gelöscht werden, wenn sicher ist, dass der Controller oder Subagent nicht läuft. In der Regel will man das der Engine überlassen.
Correlation-IDs (CorrelId
)
- Für Debugging-Zwecke kennt die JS7-Engine jetzt CorrelIds, mit denen sich asynchrone Operationen im Protokoll verfolgen lassen, teilweise über HTTP und mehrere Knoten hinweg.
- Um die im Debug-Protokoll sichtbar zu machen, braucht es im log4j-Pattern die Stelle »
%notEmpty{%X{js7.correlId} }
« (mit Zwischenraum am Anfang). CorrelIds sind 8 Zeichen lang und enthalten nur Zeichen, die ein Regex-Wort bilden, das sich mit einem Mausklick markiert lässt, sodass sich leicht weitere Zeilen mit derselben CorrelId auffinden lassen. Weil sie eine feste Länge haben, ist es am besten sie vor den variable langen Teilen, also vor %logger einzufügen.
<patternLayout charset="UTF-8" pattern=
"%d{DEFAULT_MICROS} %-5level{INFO=info, DEBUG=debug, TRACE=trace} %notEmpty{%X{js7.correlId} }%logger - %message%n"
/>
v2.3.2
v2.3.2-beta.20220510
- FIX Controller restart fails with "Application of snapshot object 'VersionedItemRemoved' failed in record"
v2.3.2-beta.20220506
- Bei X.509-Zertifikaten, mit denen die Zertifikate im signierten Item beglaubigt werden, braucht das OID 2.5.29.19 "May act as CA" nicht mehr critical sein.
- Der bloße Subagent hat zwei neue Webservices, die kompatibel mit den bisherigen Agenten-Webservices (des Direktors) sind:
/agent/api
liefert ein SubagentOverview, das aussieht wie ein AgentOverview./agent/api/command
akzeptiert das KommandoShutDown
mit den optionalen ParameternprocessSignal
undrestart
.