Az utóbbi időben nem nagyon tudtam blogolni, mivel az iskola indulásával radikálisan megnőtt teendőim száma, így nagyon kevés időt hagyva bármilyen írásos önkifejezésre (kivéve a programozást). Az alábbi cikk pár érdekes sztorit mesél el az utóbbi időből.
Szaporodnak a számítógépek
Alapvetően a munkámra szeretném fogni a homelab bővítését, de – mint oly sok vásárlásom mögött – itt is a felfedezés és kísérletezés vágya hajtott. Az új szerver szintén egy Fujitsu, még a modellszáma is ugyanaz (S920), konfigurációja pedig hasonló a “főgéphez”, csak kicsit kevesebb RAM van benne. A 2-es szerver node mindössze 18 ezer forintomba került, de megnyitotta előttem az elosztott, cluster alapú számítógépes rendszerekkel való kísérletezés lehetőségét.
Közben volt egy katasztrofális meghibásodás a főszerverben (elégett benne az mSATA SSD), amit csak két nap alatt sikerült javítani (ennyit a High Availability-ről), addig is minden állt, nem mentek a weboldalak (ami miatt kaptam is az iskolatársaimtól). Itt érdemes megjegyezni, hogy mindez elkerülhető lett volna, ha a használt SSD adott volna magáról bármilyen jellegű S.M.A.R.T. adatot (mint ahogy nem adott). Az új SSD-k már rendesen figyelik magukat, így mindenki megnyugodhat…
A Proxmox clusterezése
Minden felkészültebb Proxmox admin ezen a ponton valószínűleg már nagyon el szeretne küldeni melegebb éghajlatra, mivel egy Proxmox clusterhez a Corosync (állapotmenedzsment rendszer) és Quorum (alapvetően az esetleges kimaradások esetén a számítógépek állapotát megállapító program) miatt minimum három node-ra van szükség, de mivel a jelenlegi helyzet nem követeli meg a szuper High Availability-t, így egy egyszerű konfig fájl változtatással (adtam egy extra votetot a főszervernek) tettem félig-meddig quorate-té (szavazásra képessé) a hálózatot.
Így a terhelés már két gépen oszlik meg, lehet pakolgatni össze-vissza az összes VM-et és LXC-t (sajnos csak teljes leállítás után, mivel a tárolást nem clustereztem be [még]).
Összesen így van 8 CPU-magom, 23 GB RAM-om, és több mint 1.5 TB gyors elérésű tárhelyem.
És a legszebb az egészben az, hogy mindez (tehát a két gép, switch és router, plusz a tárhelyet részben szolgáltató NAS) mindösszesen 25W-ot használ. Így nem is viszi csődbe a családot a villanyszámla… Nem úgy, mint egyesek.
Mivel:
25W = 0.025 kWh
ami éves szinten 8765 üzemóra,
ami 291 kWh fogyasztásnak felel meg (ami olyan 7800 forint).
Osztás nullával
És most jön a legjobb, várva várt rész, de mielőtt elmesélem a nullával osztás történetét, egy kis háttér. Munkám során informatikai támogatást nyújtok egy EU-s projektben, ami így magában foglalja a programozást is (mivel nem a következő Facebookot kell lefejleszteni, így gondoltuk, hogy még nekem is menni fog). A cél egy kérdőívező rendszer lefejlesztése volt, ami képes dinamikusan változtatni a mutatott contentet, akár a user válaszai alapján átrakosgatva azokat (ez utólag nem hangzik jól). A végén pedig (mivel ugye az egész teljesen anonim) a böngészőben legenerál egy PDF-dokumentumot, amit a kitöltő letölthet. A PDF-ben lévő szöveg dinamikus, amit egy háttéradatbázis alapján generál le a rendszer.
Tehát ez a specifikáció, de mi a megoldás? Nézzük a tech stacket:
Backend:
- Webszerver: Apache2, később NGINX
- DB: sqlite3 (tervezett a LiteStream alapú replikáció és a több zóna, ha elég user lesz)
- A backendet itt a Pocketbase adja, ami bár nem iparági sztenderd, de nagyon gyors és stabil, plusz lehet JS-ben szkriptelni, ami azt jelenti, hogy ugyanúgy programozhatom, mint az eddigi Express alapú backendjeimet (csak egy kicsit nehezebb, mert nem node.js a backend nyelve, hanem egy minimalista JSVM implementáció).
Frontend:
- ReactJS, React Routerrer és egy valag egyéb csomaggal (React-PDF, pocketbase sdk, stb…)
- Más itt nincsen, alapvetően minden a Reacton alapul
Nehézségek
Mik is voltak a főbb nehézségek? Először is: nem nagyon kéne 36 oldalas PDF-et generálni a böngészőben. De ez még csak a felszínt kapargatja, hiszen a terv számos egyéb sebből vérzett: Az oldalnak jól kellett kinéznie és ugyanakkor gyorsnak kellett lennie, egyszerűnek kellett lennie, ugyanakkor szofisztikáltnak. És akkor itt vagyok én, a magányos webdev, akinek mindenkivel harcolnia kell minden featurért.
A frontendet szétoptimalizáltam, minden, ami nem szöveg volt, az egy SVG-ből töltött be, amit előtte minifikáltam és összetömörítettem (plusz GZIP-et is rakott rá még e webszerver). Így nem is néz ki olyan rosszul az oldal.
Pontozás
A kérdőívet összeállító szakmai csapat egy bonyolult pontozással állt elő: minden kérdést máshogyan osztályozunk, de a végén modulonként (tehát témánként) egy egységes 0 és 100 közötti százalékos értéket számítunk. Ezen értékek százalékos átlaga adja az össz-százalékot.
A kérdéseket a következő módokon lehet osztályozni:
- Sima: 0 és n közötti pontok, ahol n pozitív valós szám
- Tükrös: -n és n közötti pontok, ahol n valós szám (itt főleg a különféle veszélyekre kell gondolni [gazdasági, politikai helyzet, stb.)
- Egyéb (ez lett az alapértelmezett): -k és n között, ahol mind n, mind k valós szám
Ezeket az alábbi összegző függvénnyel kezeltem:
function handlePercentage(score, minScore, maxScore) { //No score available if (isNaN(score / minScore) === true && isNaN(score / maxScore) === true) { return 0 } if (minScore === 0 && maxScore === 0 && score === 0) { return 0; } if (minScore !== 0 && maxScore === 0) { if (isNaN(score / minScore)) { return 100 } return 100 - Math.abs(score / minScore) * 100; } if (minScore === 0 && maxScore !== 0) { if (isNaN(score / maxScore)) { return 0 } return (score / maxScore * 100) } if (Math.abs(minScore) === Math.abs(maxScore)) { if (isNaN(score / maxScore)) { return 0 } var projectedMaxScore = maxScore * 2 return ( (score + maxScore) / projectedMaxScore * 100) } var projectedMaxScore = maxScore + Math.abs(minScore) return ( (score + Math.abs(minScore)) / projectedMaxScore * 100) }
Itt volt gond a nullával, mivel az lehet 100%, 0% és 50% is, ugyanabban a kérdőívben. Több darab, félóránál hosszabb telefonbeszélgetésbe tellett, mire megértettem, hogy mit is kell csinálni. Végül a pontszámokat el is kellett rejteni a PDF-ben (nehogy megijedjen tőle valaki).
A pontszámok alapján ezután intervallumot keres a rendszer és legenerálja a személyre szabott gazdaságértékelést.
Logika
A program igazi ütőkártyája a programozhatóság: minden kérdés látja a többi kérdés (és a saját) válaszait, ami alapján át tudja programozni magát és a többi kérdést. Így lehet, hogy egy 36 kérdéses ívből lehet 34, de akár 45 darab kérdéses változat is (mindezt láthatatlanul teszi a rendszer). Ehhez a keretrendszer (SurveyJS) szkriptnyelvét hívtam sgítségül:
{ "type": "radiogroup", "name": "g154", "scoringCategory": "Üzletvitel, foglalkoztatás és innováció", "title": "Részt vesznek-e 30 év alatti fiatalok (munkavállalók vagy családtagok) a gazdálkodásban, és mi a részvételük legmagasabb szintje?", "visibleIf": "{a9} anyof [ 'Családi munkaerő', 'Időszakos, fizetett munkaerő', 'Állandó, fizetett alkalmazottak' ] and {a9} notempty", "isRequired": true, "choices": [ .... ] }
Ez egy viszonylag egyszerűen megérthető logikai feltétel (a “visibleIf” sor a lényeg), de vannak viccesebbek is:
{ "value": "A munkavállalók fizetése, juttatásai", "text": "A munkavállalók fizetése, juttatásai", "visibleIf": "( {inheritedType} contains 'SZN' or {inheritedType} contains 'SZK' or {inheritedType} contains 'Ü' or {inheritedType} contains 'NH' or {inheritedType} contains 'IÁ' or {inheritedType} contains 'EÁ' ) and ({a9} anyof ['Időszakos, fizetett munkaerő', 'Állandó, fizetett alkalmazottak' ] and {a9} notempty)" },
És ilyenből van kb. 50 az adatbázisban…
Ilyen egy kész jelentés (kivettem a válaszokat, mivel az már személyes jellegű adat):
kerdoivLényeg
Az utóbbi pár hónap meglehetősen kalandos volt: nagyon sokat dolgoztam az új szoftveren, megismertem az informatika (és a fáradtság) újabb mélységeit, emellett letoltam három OKTV-t is (fizika, német, angol), illetve megpróbáltam levizsgázni vezetésből, eddig sikertelenül. Tanulság: ne vállalj el teljesíthetetlen feladatot, de azért néha állítsd magad kihívások elé.
Leave a Reply