Range Retention (Preview)
Heute friert ein kompiliertes Modell jeden Abhängigkeitsbereich zu einem exakten Pin ein: System-[2.5,3.0) in der ckModel.yaml wird zu System-2.5.0 im kompilierten Modell, und ein Tenant muss genau diese Version vorhalten (siehe Versionierungsregeln). Jede neue System-Version zwingt daher jeden Dependent, neu gebaut und neu veröffentlicht zu werden.
Range Retention behält stattdessen den deklarierten Bereich im kompilierten Modell. Ein Range-Retention-Modell bleibt nutzbar, wenn ein additives Minor seiner Abhängigkeit installiert wird — ohne Neubau, ohne Versionssprung.
Range Retention wird mit dem Flag OctoCkRangeRetention=true eingeschaltet. Sie ist standardmäßig aus; bei ausgeschaltetem Flag ist die kompilierte Ausgabe byte-identisch zu vorher. Verwenden Sie sie nur für die lokale Evaluierung und veröffentlichen Sie niemals Range-Retention-Basismodelle in einem gemeinsamen Katalog (siehe die Betriebsregel); das einmalige Neu-Pinnen aller Modelle ist für eine spätere Phase geplant.
Einschalten
| Wo | Wie |
|---|---|
| MSBuild (Modellprojekt) | <OctoCkRangeRetention>true</OctoCkRangeRetention> oder dotnet build -p:OctoCkRangeRetention=true |
| Umgebung | OctoCkRangeRetention=true (MSBuild übernimmt eine exportierte Variable als Property) |
octo-ckc Compile | -rr true (Standardwert ist die Umgebungsvariable) |
Das Flag funktioniert gleichermaßen für CK-Language-1- und CK-Language-2-Modelle.
Was der Compiler schreibt
# ckModel.yaml (source)
modelId: Acme.Plant-1.0.0
ckLanguage: 2
dependencies:
- System-[2.5,3.0)
- Acme.Assets-[1.0,2.0)
# compiled with OctoCkRangeRetention=true
dependencies: # exact closure, kept for older readers and the SemVer diff
- Acme.Assets-1.0.0
- System-2.5.0
dependencyRanges: # every declared dependency: range verbatim + floor
- range: Acme.Assets-[1.0,2.0)
floor: 1.0.0
- range: System-[2.5,3.0)
floor: 2.5.0
usedSurface: # what this model uses of System (sorted)
- System@2/Entity-1
- System@2/Entity-1.Name
usedSurfaceHash: sha256:…
minEngineVersion: 3.5.1
types:
- typeId: Pump
derivedFromCkTypeId: Acme.Assets@1/Device-1 # major-qualified, version-less
implements:
- Acme.Assets@1/Calibratable-1
dependencyRangeslistet jede deklarierte Abhängigkeit mit ihrem Bereich und ihrem Floor.- Der Floor ist die deklarierte Untergrenze (
[2.5,3.0)→2.5.0), niemals „die höchste Version im Katalog“. Eine exklusive Untergrenze erhält den nächsten Patch ((2.4,3.0)→2.4.1). - Jede Referenz in eine Abhängigkeit ist Major-qualifiziert und ohne Modellversion:
Model@Major/Element-n, z. B.System@2/Entity-1. Referenzen auf die eigenen Elemente des Modells bleiben konkret. usedSurfacelistet pro deklarierter Abhängigkeit die Elemente und Member dieser Abhängigkeit auf, die das Modell verwendet: Basistypen und -Records, implementierte und erweiterte Interfaces, wiederverwendete Attributdefinitionen, als Werttypen verwendete Records und Enums, Assoziationsrollen und -ziele (Elementebene,System@2/Entity-1) sowie Attributpfade von Indizes undownerAttributePathin einen geerbten Typ der Abhängigkeit (Member-Ebene,System@2/Entity-1.Name).usedSurfaceHashist ein sha256 über die Liste. Eine spätere Importprüfung (F2.5) nutzt ihn, um zu erkennen, welchen Konsumenten eine Änderung der Abhängigkeit brechen würde. Sie kann Verhaltens- oder semantische Änderungen (Standardwerte, Anzeigeregeln, die Bedeutung eines Werts) nicht erkennen, und Referenzen in nicht deklarierte, transitive Abhängigkeiten werden nicht aufgelistet.minEngineVersionwird gesetzt, und das Modell wird unterck-models/v3/veröffentlicht.
Prüfungen zur Compile-Zeit
- Ein Major pro Bereich. Da Referenzen als
Name@<major>des Floor-Majors gespeichert werden, muss jeder deklarierte Bereich innerhalb eines Majors bleiben.System-[2.5,3.0)wird akzeptiert;System-2.5(=>= 2.5.0),System-[2.0,),System-[2.5,3.0]undSystem-[2.5,4.0)werden abgelehnt („... admit more than one major version ...“). Ein neues Major ist eine bewusste Änderung des Dependents. - Gegen den Floor kompilieren, gegen die höchste Version verifizieren. Das Modell wird gegen die höchste Version im Bereich aufgelöst und validiert, aber jedes Element, auf das es in einer Abhängigkeit verweist, muss bereits in der Floor-Version existieren (oder, falls der Floor selbst nie veröffentlicht wurde, in der niedrigsten verfügbaren Version im Bereich). Andernfalls: „references elements that do not exist at the floor of its dependency range ...“. Heben Sie den Floor in der
ckModel.yamlan, wenn Sie ein neueres Element benötigen. - Transitive Referenzen. Ein Modell darf Elemente eines Modells verwenden, das es nicht deklariert (über eine andere Abhängigkeit). Diese Referenzen werden ebenfalls Major-qualifiziert und gegen den Floor geprüft, und zwar gegen die Zusicherung des dazwischenliegenden Modells; ein Fehlschlag fordert Sie auf, das Modell in der
ckModel.yamlzu deklarieren. Es wird empfohlen, jedes referenzierte Modell zu deklarieren.
Wie ein Range-Retention-Modell aufgelöst wird
Eine Abhängigkeit eines Range-Retention-Modells ist erfüllt, wenn die installierte (oder Katalog-)Version innerhalb des Bereichs und auf oder über dem Floor liegt. Major-qualifizierte Referenzen binden an die installierte Version desselben Namens und Majors. Klassische Modelle behalten ihre Semantik des exakten Pins.
Beispiel: Acme.Plant-1.0.0 oben wurde gegen Acme.Assets 1.0.0 kompiliert. Wenn ein Tenant auf ein additives Acme.Assets 1.1.0 upgradet, bleibt Acme.Plant Available und löst gegen 1.1.0 auf — ohne Neukompilierung. Ein klassischer (exakt gepinnter) Dependent im selben Tenant geht auf ResolveFailed, bis er neu gebaut wird.
In einem Tenant
- Ein Range-Retention-Modell wird mit seinen
dependencyRangesgespeichert; seine Referenzen werden in der versionslosen Form (System@2/Entity-1) persistiert und erst beim Laden des Modells an die installierte Version gebunden. - Nach jedem Import validiert die Engine die installierten Modelle erneut. Ein Range-Retention-Modell wird anhand seines Bereichs und Floors beurteilt, ein klassisches Modell anhand seiner exakten Pins. Ein additives Minor einer Abhängigkeit lässt Range-Retention-Dependents daher
Available, während exakt gepinnte aufResolveFailedgehen. - Die Installation einer Abhängigkeit unterhalb des Floors (zum Beispiel durch ein explizites Downgrade) versetzt den Dependent in
ResolveFailed; das Log nennt den Bereich, den Floor und die installierte Version (Acme.Assets-[1.0,2.0) (floor 1.1.0): installed Acme.Assets-1.0.0). Er erholt sich automatisch, sobald wieder eine passende Version installiert ist.
Bekannte Einschränkungen
- Gemischter exakter Pin und Bereich an einem Modell in einem Compile. Zieht ein Range-Retention-Compile eine klassische Abhängigkeit hinein, die
System-2.5.0exakt pinnt und selbstSystem-[2.5,3.0)deklariert, während der Katalog bereitsSystem 2.6.0enthält, lösen beide zu unterschiedlichen Versionen auf, und der Compile schlägt mit Meldung 66 fehl (Multiple versions of construction kit model 'System'). Bauen Sie die exakt gepinnte Abhängigkeit mit Range Retention neu. In einem Tenant kann dies nicht passieren — ein Tenant hält genau eine Version. - Zwei Bereiche an einem Modell in einem Compile. Bereiche auf dasselbe Modell werden in einem Compile unabhängig voneinander aufgelöst. Benötigt eine Abhängigkeit
B-[1.0,1.5)und eine andereB-[1.2,2.0), können sie zu unterschiedlichen Versionen (1.4 und 1.8) auflösen, und der Compile schlägt mit Meldung 66 fehl, obwohl 1.4 beide erfüllt. Gleichen Sie die Bereiche an. - SemVer. Das SemVer-Gate klassifiziert
dependencyRangesnoch nicht; die exaktedependencies-Closure wird weiterhin wie bisher verglichen. - Ohne das Flag kompilierte Modelle behalten ihre exakten Pins und exakten Referenzen, bis sie damit neu gebaut werden.