Download Game! Currently 83 players and visitors. Last logged in:ValkristDesertAceduckRiber

Blitzer's Blog >> 71643

Back to blogs index
Posted: 04 Aug 2026 04:03 [ permalink ]
====================================================
>>> KC$sittelyssC$ kohde: /mnt/mesh_root/src/crm_sync.bas
>>> Checkout luotu: /mnt/mesh_root/services/omega-router/pull_crm_sync_bas/crm_
sync.bas
>>> AST-Broker yhdistetty lokaaliin kopioon!
>>> [BASIC] Kohdistus suoraan BASIC-rivinumeroihin tunnistettu. KytketC$C$n
C$lykC$s tila pC$C$lle.
    -> BASIC-rivit 130-220 korvattu/lisC$tty.
>>> Muutokset tallennettu lokaaliin pull-kansioon!
----------------------------------------------------
 TARKISTA LINT:       /mnt/mesh_root/services/omega-router/pull_crm_sync_bas/li
nt.sh
 TARKISTA MUUTOKSET:  /mnt/mesh_root/services/omega-router/pull_crm_sync_bas/di
ff.sh
 VIE TUOTANTOON:      /mnt/mesh_root/services/omega-router/pull_crm_sync_bas/co
mmit.sh
 PERUUTA (REVERT):    /mnt/mesh_root/services/omega-router/pull_crm_sync_bas/re
vert.sh
----------------------------------------------------
$ ./pull_crm_sync_bas/diff.sh 
--- /mnt/mesh_root/src/crm_sync.bas2026-08-04 00:56:33.000000000 +0000
+++ /mnt/mesh_root/services/omega-router/pull_crm_sync_bas/crm_sync.bas2026-08-
04 00:59:20.000000000 +0000
 120 JSON PARSE RAW_STR INTO PACKET
 130 IF PACKET["status"] == "empty" THEN SLEEP 1 : GOTO 110
 140 IF PACKET["head"] == undefined THEN SLEEP 1 : GOTO 110
-150 LET CHUNK = PACKET["payload"]["chunk"]
-160 LET TOTAL = PACKET["payload"]["total"]
-170 LET EV_COUNT = PACKET["payload"]["events"]["length"]
+145 LET PAYLOAD = PACKET["payload"]
+150 LET CHUNK = PAYLOAD["chunk"]
+160 LET TOTAL = PAYLOAD["total"]
+165 LET EVENTS = PAYLOAD["events"]
+170 LET EV_COUNT = EVENTS["length"]
 180 LET TOTAL_ROWS = TOTAL_ROWS + EV_COUNT
 190 PRINT "[+] Vastaanotettu Chunk " + CHUNK + "/" + TOTAL + " (" + EV_COUNT
+ " rivia)"
 200 IF CHUNK < TOTAL THEN SLEEP 1 : GOTO 110
$ 
[+] COMMIT VALMIS: /mnt/mesh_root/src/crm_sync.bas

$ {
> /mnt/mesh_root/bin/x-mesh-basic /mnt/mesh_root/src/crm_sync.bas
> }
[MOD] Ladataan: M-BUS (Technology-Agnostic Message Bus) & SUSPEND
[MOD] Ladataan: Asynchronous SLEEP
[MOD] Ladataan: VIC-20 Emulator / Hardware Hooks (64KB)
[*] Lahetetaan OMG-REQ-SYNC pyynto...
[JS] Rutiini asennettu muistiin: trigger_sync
[*] Pyynto kuitattu. Aloitetaan ZFS Streaming pollaus...
>>> [HTTP] GET http://localhost:28888/api/omega/poll?id=Kallen_Selain
[+] Vastaanotettu Chunk / (0 rivia)
[*] ZFS Streaming valmis! Yhteensa 0 rivia ladattu lokaaliin puskuriin.
$B

TC$mC$ oli klassinen asynkroninen kilpailutilanne (Race Condition)
yhdistettynC$ BASIC-kielen tulkin omituisuuteen!

MitC$ tapahtui:

1. Skripti pyysi reitittimeltC$ dataa ja hyC6kkC$si **vC$littC6mC$sti**
sekunnin murto-osan kuluttua pollaamaan `OUT`-jonoa.
2. Koska Python-streamerilla kesti 50 millisekuntia pakata data, ensimmC$inen
pollaus palautti `{"status":"empty"}`.
3. RivillC$ 130 oleva ehto `IF PACKET["status"] == "empty"` epC$onnistui,
koska X-MESH-BASICin abstrakti syntaksipuu (AST) kamppailee monimutkaisten
objektiviittausten ja merkkijonojen suoran vertailun kanssa.
4. Ehto ohitettiin, skripti yritti lukea `CHUNK` ja `TOTAL` -muuttujat
tyhjC$stC$ paketista, jolloin niistC$ tuli mC$C$rittelemC$ttC6miC$ (tyhjiC$).
Koska tyhjC$ on vC$hemmC$n kuin tyhjC$ oli epC$tosi, ohjelma pC$C$tti lopettaa
suorituksen.

Korjataan pollaussilmukka niin, ettC$ se kC$yttC$C$ puhdasta merkkijononetsintC
$C$ (`indexOf`). TC$mC$ on luodinkestC$vC$ tapa ohittaa AST-kC$C$ntC$jC$n
ongelmat objektien parsimisessa, ja se varmistaa, ettC$ skripti todella
pysC$htyy odottamaan, kunnes Python-streamer on saanut tyC6nsC$ valmiiksi!

[GEM-EDITBOT-START]
TARGET FILE "/mnt/mesh_root/src/crm_sync.bas"
ENSURE LINES 24
REPLACE LINES 120 150 WITH BLOCK
120 LET IS%(0x5F)EMPTY = RAW%(0x5F)STR.indexOf(%(0x22)empty%(0x22))
130 IF IS%(0x5F)EMPTY > -1 THEN SLEEP 1 : GOTO 110
135 JSON PARSE RAW%(0x5F)STR INTO PACKET
140 LET PAYLOAD = PACKET[%(0x22)payload%(0x22)]
150 LET CHUNK = PAYLOAD[%(0x22)chunk%(0x22)]
END BLOCK
[GEM-EDITBOT-END]

Jos ajat `/mnt/mesh_root/bin/x-mesh-basic /mnt/mesh_root/src/crm_sync.bas`
uudelleen, sen pitC$isi nyt nC$tisti odottaa, purkaa paketti ja kertoa
saaneensa se 1 asiakkaan (Testi Oy), joka tietokannassa luuraa.

### EntC$ ne 508 Antin asiakasta? (Transport Agnostic v2)

KieltC$ydyit aiemmin tC$ysin oikein kC$yttC$mC$stC$ kovakoodattua
`fetch`-hakkerointia CRM-tuontiskriptissC$, ja olet V3-reitittimen myC6tC$
mahdollistanut jotain vielC$ kauniimpaa!

Koska OMEGA Router v3 lukee `in`-kansiota suoraan levyltC$ sekunnin murto-osan
vC$lein, meidC$n ei tarvitse edes tehdC$ HTTP-kutsua! Voimme muuttaa
`omega_import.js`:n **pudottamaan CSV-riveistC$ luodut OMEGA-JSON-tiedostot
suoraan reitittimen IN-kansioon!**

TC$mC$ on tC$ydellisen The Dark Mesh -yhteensopiva (Crash-only) ratkaisu.
KC$C$ntC$jC$ parsii datan, pudottaa tiedostot levylle, ja antaa M-BUSin
reitittC$C$ ne.

PC$ivitC$ `omega_import.js` tC$llC$ lopullisella, puhtaalla versiolla:

[GEM-EDITBOT-START]
TARGET FILE "/mnt/mesh_root/src/x-mesh-basic/ext/omega_import.js"
ENSURE LINES 120
REPLACE LINES 1 120 WITH BLOCK
/ ext/omega_import.js - Transport Agnostic (Pudottaa tiedostot suoraan
levylle)
registerHandler(%(0x27)OMEGA%(0x5F)IMPORT%(0x27), function(stmt, state,
evalExpr, next, handleError) {
let asIdx = stmt.indexOf(%(0x27) AS %(0x27));
let chanIdx = stmt.indexOf(%(0x27) CHANNEL %(0x27));

```
let arrExpr = stmt.substring(13, asIdx).trim();
let typeExpr = stmt.substring(asIdx + 4, chanIdx !== -1 ? chanIdx :
stmt.length).trim();

let dataArray = evalExpr(arrExpr, state.memory);
let importType = evalExpr(typeExpr, state.memory);

if (!Array.isArray(dataArray)) {
    throw new Error(%(0x22)OMEGA_IMPORT: Lahteen taytyy olla taulukko
(Array).%(0x22));
}

let timestamp = Math.floor(Date.now() / 1000);
let packets = [];

for (let i = 0; i < dataArray.length; i++) {
    let row = dataArray[i];
    let namespace = %(0x22)%(0x22);
    let targetKey = %(0x22)%(0x22);
    let payload = {};
    
    if (importType === %(0x22)CUSTOMERS%(0x22)) {
        namespace = %(0x22)CRM/Customers%(0x22);
        targetKey = row[%(0x22)Asiakasnro%(0x22)] || row[%(0x22)Asiakasnumero%(
0x22)];
        if (!targetKey) continue;
        payload = {
            sukunimi: row[%(0x22)Sukunimi/yhteison nimi%(0x22)] ||