NexusFabricCereți o prezentare

Interoperabilitate

Un integrator are nevoie de trei lucruri înainte de primul flux: ce formă are fișierul, ce adaptoare există, și ce se întâmplă când ceva cade. Pagina răspunde în ordinea aia, iar limita stă lângă capacitate, nu într-o notă de subsol.

Contractul se măsoară la capătul celălalt

Ce afirmăm despre o integrare e măsurat la capătul celălalt, pe formele unui client real, din afara procesului. Nu e ce a răspuns platforma pe ușa ei: e ce corp exact a văzut receptorul, și pe el se face verificarea.

Contează fiindcă un flux poate răspunde 200 cu valoarea greșită, iar o suită care măsoară numai statusul rămâne verde. De aceea proba unei integrări e corpul văzut de receptor, și tot de aceea limita fiecărui adaptor e scrisă lângă el, mai jos, nu într-o notă de subsol.

Ce încape într-un fișier de flux

Un flux e un singur fișier text: un frontmatter, apoi secțiuni de pași, apoi opțional o secțiune de tratare a erorii. Limbajul are un singur parser, iar parserul nu intră în panică pe nicio intrare — un fișier stricat produce o eroare care numește poziția.

Forma completă a unui fișier de flux, redusă la esențial
flow: sincronizare-contoare
tenant: acme
effects: [http_egress]
config: [ANRE_URL]
dedup_key: "{{ $.messageId }}"
queue_max_attempts: 3

## Step: verifica
```validate
$.id != null | "id is required" | syntactic
```

## Step: trimite
effects: [http_egress]
endpoint: "{{ ctx.ANRE_URL }}/ingest"

## Fault: raspunde-cu-eroare
response_status: 502

Același fișier se scrie în două feluri, după cine îl deschide. În VS Code se deschide în editorul vizual — un nod pe fiecare pas, rutele etichetate pe muchii, reordonare prin tragere, salt în subflux — iar o extensie de server de limbaj îl verifică în timp ce se scrie, cu diagnosticele la poziția din fișier. Pe disc rămâne text: se citește într-un git diff, se revizuiește ca orice altă modificare și se publică din linia de comandă.

  • Frontmatterul declară identitatea fluxului și tenantul, efectele cerute, configurarea de mediu pe care fluxul o cere de la instalație, orarul, plafonul de dimensiune, politica de coadă, nivelul de jurnalizare, cheia de deduplicare și pe cea de corelare, plus cele patru chei prin care un flux expune un serviciu gRPC — toate patru sau niciuna.
  • Corpul unui pas e un bloc marcat cu limbajul lui: ntd pentru șabloane de text și de XML, xslt pentru transformări, condition și validate pentru cele două garduri, route pentru ramificare, include și call_flow pentru biblioteci, foreach, split și fork pentru compoziție.
  • Cheile de pas acoperă restul: adresa și metoda unui apel de ieșire, anteturile lui, statusul și anteturile răspunsului, instantaneele mesajului, deschiderea unei corelări cu starea și termenul ei.

Vocabular fără executant, și ce se folosește în loc

  • Nu se rulează cod propriu într-un flux. Un pas care ar conține JavaScript e refuzat la publicare, iar asta e o decizie, nu o întârziere.
  • Patru efecte există în vocabular fără executant: ceas, aleator și cele două ale unei magazii cheie-valoare. Declarate pe un pas, primul mesaj se oprește cu o eroare care numește efectul neînregistrat. Declarate pe frontmatter, nu fac absolut nimic — nici refuz, nici avertisment. Ce funcționează în locul lor sunt funcțiile de bibliotecă, now() și uuid(), care nu cer nicio declarație.
  • Nu există validare după schemă și nici conversie de tip la transformare. Ce există e gardul validate — reguli pe mesajul sosit, fără schemă — iar o transformare care ar converti tipurile după o schemă declarată nu e construită.
  • Nu există tip temporal. De aceea formatul e obligatoriu la locul apelului — date_format(now()) — iar un timestamp randat direct într-un text e refuzat la publicare, în loc să scrie un număr sub un nume de câmp care promite o dată.

Adaptoarele și limita fiecăruia

Fiecare adaptor, cu limita lui numită pe același rând
AdaptorCe trece prin elLimita numită
SOAPO cerere SOAP trece prin **aceeași** poartă, neschimbată, iar un refuz e 401/403 HTTP simplu, niciodată un SOAP Fault.Nu se consumă un WSDL străin și nu există contract tipizat pentru un serviciu expus: WSDL-ul generat e xsd:anyType. Nu există WS-Security — o credențială din corpul mesajului nu autentifică nimic.
gRPCO ușă separată, prin aceeași poartă și aceeași paranteză de livrare ca rutele HTTP.Fără streaming pe intrare: o metodă de flux e refuzată explicit. Tabela de rutare se construiește la pornire, deci un flux publicat după aceea cere o repornire.
FișiereConectorul de fișiere citește un director și trimite ce găsește.Un flux nu scrie fișiere. Scrierea într-un director nu e o capacitate a platformei.
CompozițieUn mesaj poate fi împărțit pe ramuri, iterat sau desprins într-o ramură care nu ține răspunsul.Nu există agregare: ramurile nu se adună într-un mesaj la capăt. Reunirea rămâne de scris în flux, explicit.

Ruta care publică WSDL-ul unui serviciu expus există și e publică — un client o poate citi fără credențiale — dar numai pentru un tenant vizibil: un tenant inexistent și unul dezactivat răspund identic. Ce se citește de acolo e contractul slab tipizat din tabel, nu o schemă.

Detaliile celor două uși și ale apelurilor de ieșire sunt pe pagina de protocoale; ce fac conectorii la un refuz, pe pagina de conectori. Aici stau limitele, fiindcă ele sunt ce trebuie știut înainte, nu după.

Când o livrare eșuează

  • Un flux poate avea o secvență de tratare a erorii. Ea rulează în locul propagării, iar un handler care reușește **nu** răspunde 200: statusul rămâne cel natural al erorii care a declanșat-o.
  • Deduplicarea se declară, nu se programează: a doua livrare a aceleiași chei nu mai rulează fluxul, în fereastra declarată.
  • O corelare cerere→răspuns-întârziat are termen obligatoriu — o așteptare fără capăt e o scurgere, nu o politică — iar una depășită se reconciliază de la sine.
  • O livrare ieșită pe secvența de tratare **nu** se comite ca reușită.

Patru comportamente care surprind un integrator

  • Pe o coadă, o secvență de tratare care reușește **confirmă** mesajul: fără reîncercare și fără coadă moartă. Un handler adăugat pentru ușa sincronă și uitat acolo dezarmează tăcut coada moartă a fluxului. Dacă se vrea și una și alta, handlerul trebuie să se încheie cu un pas care eșuează.
  • Fiindcă o livrare tratată nu se comite ca reușită, un duplicat al aceleiași chei rulează **tot** fluxul din nou — inclusiv secvența de tratare, și inclusiv efectele deja consumate de livrarea eșuată. Contabilitatea efectelor nu e construită.
  • Pe un flux care are și închidere de corelare, a doua livrare a aceleiași chei pornește și moare pe „corelarea e deja închisă", înaintea primului pas — deci secvența de tratare nu vede refuzul, iar un corp corectat nu ajută.
  • Antetul de corelare dintr-un răspuns redat numește livrarea care a **deschis** rândul, nu pe cea al cărei corp se redă. Cine urmează antetul ca să găsească originalul în jurnal aterizează pe o livrare care s-a terminat în eroare.

Plafonul unui mesaj

Nu există un plafon unic pe instalație. Se rezolvă per punct de acces, pe trei straturi, de la general la specific: valoarea instalației, valoarea fluxului, valoarea unui pas de ieșire. Un corp care își anunță dimensiunea peste plafon e refuzat fără să se citească un octet din el.

Ce nu e construit, spus fiindcă altfel se citește ca promisiune: sub plafon, un corp e în continuare materializat **și parsat** în memorie, deci un plafon urcat cumpără transport la un cost de memorie de același ordin. Nu există contabilitate a memoriei materializate cu refuz temporar și indicație de reîncercare, și nu există contoare de refuzuri per punct de acces în interfață.

Publicare, versiuni și ce nu face validatorul

Publicarea e o poartă, nu o copiere de fișier. Compilează fluxul, cere un tenant înregistrat, verifică plafoanele declarate și forma blocurilor de rutare, și refuză o transformare în afara subsetului acceptat — cu construcția numită. Refuzurile vin în clipa publicării, nu la primul mesaj din producție.

Ce nu face validatorul de dinainte de publicare: nu există rulare în sec, nu există publicare pe o felie de trafic cu promovare ulterioară, iar referința pe care publicarea o mută se mută chiar dacă artefactul are erori semantice care apar abia la rulare. Iar două liste se fotografiază la pornire și nu se reîmprospătează singure — fluxurile cu orar și tabela de rutare gRPC — deci un flux nou pe una din ele cere o repornire.

Site-ul descrie versiunea 1.2.0. Distribuția e comercială, cu licență proprietară; codul sursă nu e public.