Przejdź do treści

Platformy i rozmieszczenie

Adnotacja platformy opisuje kontekst wykonania zadania. deployment jest odrębną deklaracją opisu rozmieszczenia. Poniżej rozdzielamy składnię, walidację profili i podzbiór interpretowany przez obecny kompilator. Przyjęcie źródła ani utworzenie planu nie dowodzi uruchomienia systemu.

Składnia platform

platformAnnotation
    : AT platformTarget (LPAREN platformArgument (COMMA platformArgument)* RPAREN)?
    ;
platformTarget
    : EMBEDDED
    | SERVER
    | REPORT
    | EDGE
    | CLOUD_SERVER
    | MOBILE
    | DESKTOP
    | WEB
    | MICROCONTROLLER
    | FOG_NODE
    | DATA_CENTER
    | IDENTIFIER // Forward-compatible: nowe platformy bez zmiany gramatyki
    ;
platformArgument
    : anyIdentifier ASSIGN platformValue // klucz=wartość
    | platformValue                      // positional
    ;
platformValue
    : literal
    | anyIdentifier
    ;

R01 — konteksty wykonania

Zapis Kontekst
@embedded Urządzenie lub środowisko wbudowane
@server Środowisko serwerowe
@report Część raportowa / prezentacyjna

Gramatyka dopuszcza również pozostałe nazwy wymienione w platformTarget i dowolny IDENTIFIER. Nie jest to katalog zaimplementowanych wykonawców. Nieznana platforma może przejść check z ostrzeżeniem W5000 o pominięciu walidacji zdolności. rest, grpc i mqtt opisują wiązania protokołów; nie należą do trzech podstawowych kontekstów.

Przy task gramatyka dopuszcza zero lub więcej adnotacji. Próby bez adnotacji oraz z @server @report przechodzą check; nie ustanawia to kompletnego kontraktu wyboru wykonawcy lub uruchomienia wielu kopii zadania. @server nie wskazuje konkretnego hosta, chmury ani osobnego procesu.

R02 — argumenty i profile

Nawiasy są opcjonalne, ale po ich otwarciu wymagany jest co najmniej jeden argument. @embedded() jest błędem składni. Argument może być pozycyjny albo nazwany (klucz=wartość); wartość jest literałem lub identyfikatorem, nie dowolnym wyrażeniem.

Obecny PlatformValidator wybiera wariant z pierwszego argumentu pozycyjnego. Jeśli wskazuje on zadeklarowane device, walidator sięga do wariantu tego urządzenia. Jest to rozwiązywanie profilu zdolności, nie dowód połączenia z fizycznym sprzętem. Przy braku dostępnego profilu wariantu może pojawić się W5014 i użyty zostaje profil domyślny; nie jest to potwierdzenie obsługi wariantu.

Walidator sprawdza wybrane wymagania zadeklarowane w argumentach:

Wymaganie Obecna kontrola
memory Dodatnia, rozpoznana wartość ponad limitem profilu: błąd E5001; ponad 80% limitu, ale w limicie: ostrzeżenie W5002.
wifi, networking Wartość wymagająca zdolności przy braku obsługi sieci w profilu: E5003.
fileIO, threading Analogiczne sprawdzenie zdolności, błąd E5003.

To porównanie deklaracji z profilem, nie pomiar pamięci ani analiza wszystkich operacji wykonywanych przez program. Nieznany argument mystery=true przeszedł próbę bez diagnostyk; nie ma tu dowodu pełnej walidacji kluczy i typów argumentów. Walidator ma również kontrole plików profili i ich dziedziczenia; plik profilu nie jest konstrukcją składni .jnx.

Deklaracja device

deviceDeclaration
    : DEVICE IDENTIFIER platformAnnotation LBRACE deviceMember* RBRACE
    ;

device ma nazwę i jedną adnotację platformy. Opis urządzenia jest odrębny od zadania. Powiązanie nazwy urządzenia z wariantem w walidatorze nie ustanawia liczby instancji zadania, identyfikacji urządzenia w sieci ani procedury instalacji.

Składnia deployment

deploymentDeclaration
    : DEPLOYMENT (STRING_LITERAL | IDENTIFIER)? deploymentBody
    ;
deploymentBody
    : LBRACE deploymentContent* RBRACE
    ;
deploymentContent
    : deploymentBody
    | ~(LBRACE | RBRACE)
    ;

R03 — granica gramatyki

Nazwa deployment jest opcjonalna; może być identyfikatorem albo literałem tekstowym. Ciało zachowuje tokeny i zagnieżdżone nawiasy klamrowe. Parser nie definiuje osobnej, ustrukturyzowanej gramatyki pól target, wpisów zadań ani replicas. Dlatego poprawne parsowanie ciała nie oznacza poprawnego opisu wdrożenia.

R04 — rozpoznawany podzbiór implementacji

DistributedTopologyLowerer przeszukuje zachowane ciało za pomocą wyrażeń regularnych. Rozpoznaje następujący wzorzec (zobacz sprawdzony przykład poniżej):

deployment Production {
    target server {
        Worker @server { replicas: 3 }
    }
}

Rozpoznawane bloki target to wyłącznie embedded, server i report. Rozpoznawany wpis zawiera nazwę zadania, adnotację jednej z tych platform oraz ciało w klamrach. Opcjonalne argumenty adnotacji są dopasowywane tekstowo; ta ścieżka nie waliduje ich jako profilu platformy.

  • Nieznane zadanie w rozpoznanym wpisie: błąd D6101.
  • Platforma wpisu różna od platformy otaczającego target: błąd D6102.
  • D6102 nie porównuje wpisu z adnotacją deklaracji task.
  • Liczba instancji jest odczytywana z pierwszego dopasowania pola repliki, replicas, instancje lub instances, po którym występuje dwukropek i cyfry. Przy braku dopasowania przyjmowane jest 1.
  • Plan zapisuje nazwę deployment, zadanie, platformę, liczbę instancji oraz znacznik jawnego rozmieszczenia. Sam wpis w planie nie potwierdza utworzenia replik.

To opis istniejącego algorytmu, nie kompletna gramatyka normatywna ciała deployment. Nieznane pola nie stają się wykonywalne przez samo zachowanie ich w IR.

R05 — rozmieszczenie wnioskowane

Jeżeli zadanie nie otrzymało żadnego poprawnie rozpoznanego jawnego wpisu, kompilator dodaje po jednym wpisie planu dla każdej odrębnej platformy jego adnotacji, z liczbą instancji 1 i znacznikiem rozmieszczenia niejawnego. Zadanie bez adnotacji nie dostaje wpisu na tej ścieżce.

Dla wpisów wnioskowanych używana jest etykieta pierwszego deployment; przy jej braku tekst implicit. Dla jawnego wpisu bez etykiety używany jest tekst default. Są to obecne wartości implementacji, nie reguła izolacji wdrożeń. Zbiór zadań rozmieszczonych jawnie jest wspólny dla wszystkich deklaracji; nie należy zakładać niezależnego uzupełniania każdej z nich.

Sprawdzone przykłady

Każda para jest sprawdzana przez CLI w osobnym projekcie. Testy potwierdzają przyjęcie lub odrzucenie źródła, bez wdrażania go na platformie docelowej.

Przykład poprawny

task Sample() @embedded(esp32c3) -> chan<Float> {
    send 21.0
}

task Display(values: chan<Float>) @report {}

Kontrola: przykład przyjęty przez check. Nie jest to test wykonania.

Przykład błędny

task Sample() @embedded() {}

Powód: Nawiasy argumentów adnotacji nie mogą być puste.

Kontrola: przykład odrzucony przez check; kody: P0001.

Pełny zakres weryfikacji przykładów.

Przykład: Jawne rozmieszczenie i nieznane zadanie

Poprawny zapis

task Worker() @server {}
deployment P { target server { Worker @server { replicas: 3 } } }

Kontrola: przykład przyjęty przez check. Nie jest to test wykonania.

Błędny zapis

task Worker() @server {}
deployment P { target server { Missing @server {} } }

Powód: Rozpoznane rozmieszczenie musi odwoływać się do istniejącego zadania.

Kontrola: przykład odrzucony przez check; kody: D6101.

Pełny zakres weryfikacji przykładów.

Przykład: Zgodność wpisu z blokiem target

Poprawny zapis

task Worker() @server {}
deployment P { target server { Worker @server { replicas: 3 } } }

Kontrola: przykład przyjęty przez check. Nie jest to test wykonania.

Błędny zapis

task Worker() @server {}
deployment P { target report { Worker @server {} } }

Powód: Wpis Worker @server znajduje się w bloku target report. Ta diagnostyka porównuje wpis z blokiem, nie z adnotacją deklaracji task.

Kontrola: przykład odrzucony przez check; kody: D6102.

Pełny zakres weryfikacji przykładów.

Przykład: Wymaganie pamięci wobec profilu

Poprawny zapis

task Sensor() @embedded(esp32c3, memory=64KB) {}

Kontrola: przykład przyjęty przez check. Nie jest to test wykonania.

Błędny zapis

task Sensor() @embedded(esp32c3, memory=512KB) {}

Powód: Wymagane 512KB przekracza limit profilu esp32c3. To kontrola deklaracji, nie pomiar zużycia pamięci programu.

Kontrola: przykład odrzucony przez check; kody: E5001.

Pełny zakres weryfikacji przykładów.

Przykład: Wymaganie zdolności platformy

Poprawny zapis

task Sensor() @embedded(generic, networking=false) {}

Kontrola: przykład przyjęty przez check. Nie jest to test wykonania.

Błędny zapis

task Sensor() @embedded(generic, networking=true) {}

Powód: Profil embedded/generic nie obsługuje wymaganej zdolności networking.

Kontrola: przykład odrzucony przez check; kody: E5003.

Pełny zakres weryfikacji przykładów.

Wyniki prób granicznych

W próbach deployment zadanie Worker było zadeklarowane z @server.

Próba Wynik check Znaczenie wyniku
Nieznana platforma zadania @unknown przyjęte, W5000 Walidacja zdolności pominięta; brak dowodu wykonawcy.
Nieistniejący wariant embedded przyjęte, W5014 Ostrzeżenie i powrót do profilu domyślnego.
target report { Worker @server {} } odrzucone, D6102 Niezgodność wpisu z blokiem.
target report { Worker @report {} } przyjęte bez diagnostyk Niezgodność z deklaracją task ... @server nie została wykryta.
replicas: 0 przyjęte bez diagnostyk Algorytm może zapisać zero; brak kontroli dodatniej liczby.
replicas: -1 przyjęte bez diagnostyk Wzorzec liczby nie rozpoznaje minusa; według algorytmu pozostaje domyślne 1, nie ujemna liczba replik.
deployment P { nonsense: 123 } przyjęte bez diagnostyk Pole nie ma rozpoznanej interpretacji w tym algorytmie.
target mobile { Worker @mobile {} } przyjęte bez diagnostyk Ten rodzaj bloku nie jest rozpoznawany przez algorytm rozmieszczenia.

Jawne luki

  • Pełna gramatyka i walidacja ciała deployment, w tym nierozpoznanych pól, wartości, powtórzeń i zakresów liczb. Obecna interpretacja tekstowa jej nie zastępuje.
  • Zgodność jawnego rozmieszczenia z platformami deklaracji zadania.
  • Jednoznaczny kontrakt wielu adnotacji, wielu deploymentów i powtarzanych wpisów.
  • Pełna walidacja argumentów platformy i rozróżnienie niedostępnego profilu od nieobsługiwanego środowiska wykonania.
  • Powiązanie liczby instancji z uruchamianiem, rozdzielaniem danych i stanem replik.
  • Kontrakt fizycznego hosta, adresów, zasobów i instalacji. Adnotacja ani logiczny plan nie dowodzą spełnienia tych warunków.

Plan krawędzi w DistributedTopologyLowerer bierze platformy z adnotacji zadań (pierwszą albo local przy braku), a nie z jawnych wpisów rozmieszczenia. Dlatego przyjęty sprzeczny opis nie stanowi dowodu przeniesienia zadania i transportu. Zmiana platformy nie gwarantuje też przenośności kodu natywnego i bibliotek.

Podstawa w repozytorium

  • grammar/JunexisLang.g4: adnotacje, urządzenia i nieprzezroczyste ciało deployment.
  • compiler/JunexisLang.Compiler.Core/Platform/PlatformValidator.cs: warianty, odwołania do urządzeń, wymagania i diagnostyki profili.
  • compiler/JunexisLang.Compiler.Topology/DistributedTopologyLowerer.cs: rozpoznawanie wpisów, walidacja D6101/D6102 i wnioskowanie rozmieszczenia.
  • Testy compiler/JunexisLang.Compiler.Tests/Platform/ oraz compiler/JunexisLang.Compiler.Tests/Topology/DistributedTopologyLowererTests.cs.

Przykłady i testy planu nie są dowodem uruchomienia całego systemu na sprzęcie, wykonania replik ani zgodności zachowania wszystkich generatorów.