Helló
Ki akarok pár kombinatorika jellegű feladatot próbálni, hogy igazoljam a teóriám. Saját kihívás, önmagam ellen! :)
Van egyrészt egy saját PHP programom, aminek vannak bemeneti paraméterei (jó sok), és generál egy fájl kimenetet, mint eredmény.
Utána abból a fájlból még egy másik programmal kell pár változatot generáljak.
Majd van egy elemző programom, ami megvizsgálja az eredményt.
Arra gondoltam, hogy az első program meghívásához legenerálom az összes, akár milliós nagyságrendű paramétert (N), az összes lehetőséget, hogy akarom meghívni az első programot.
Ez volt az első ötlet:
Valahogy meg kellene oldani a queue kezelést, hogy 8 magból mondjuk 4 esetén ez fusson, tehát elosztom a legenerált listát 4 felé és elindítom 4 szálon, így mivel nincs queue kezelésem ez fapad megoldásként hasonló eredményt hoz. Ezzel csak az a baj, hogy lehet nincs elég helyem hozzá. Aztán a létrejött fájlokat kellene másik programmal meghívni, amiből lesz M darab változat. Így lesz N*M fájl, amihez végképp nincs elég helyem. Bár ez az én bajom. Aztán a létrejött N*M fájlt kellene elemezni, és ha valami olyan, ami oké, akkor azt meghagyni, ha nem olyan, amire 99% az esély, akkor törölni, de valahogy elrakni, hogy azt már néztem és nem volt jó.
Ez az első ötlet így nem jó számomra.
Ezek PHP nyelven írt programok és most Windowst használok, mert így kényelemes most épp, de lehetne Ubuntu linux is akár.
Második ötlet, ami jobbnak tűnik:
Azt lenne az ideális, hogy lenne egy olyan okos vezérlő, multi process/worker/batch futtató alkalmazás, ami az alábbiakat valósítaná meg:
Queue 1: (kombináció alapján generálás) Figyelne, hogy mindig legyen mondjuk 100 (vagy több, de nem sokkal) az első programmal már legenerált kombináció (az N elemeken menne végig), hogy lehessen a másik programmal (M elemek) kombinációkat legenerálni. Hogy ne fogyjon el a forrás a második lépéshez. Ez a program egy millió soros txt állományon menne végig, és abból venné sorban a paramétereket.
Queue 2: (kombináció előkészítés) Figyelné, hogy legyen mindig legenerált 100 (vagy több, de nem sokkal) elemezhető kombináció (N*M elem összesen). Ez a második folyamatosan dolgozná fel a már legenerált fájlokat és ebből jönnének létre további fájlok, amiket ki kell elemezni. Itt a már létrejött fájlból hozna létre M változatot, ha kész törölné is akár az adott elemet, amiből készítette, de ez végül is mindegy, mikor törlődik.
Queue 3: (kombináció feldolgozás, elemzés) Az előző 2 queue működésen kívül az összes egyéb erőforrással próbálná azt elérni, hogy a legenerált utóbbi, Queue 2 esetén létrejövő N*M elemet meghívni az utolsó, 3. elemző programmal, ami ha oké meghagyja a fájlt. Ha nem oké, törli és loggolja.
Elérni, hogy soha ne fogyjon ki a Queue 1 és Queue 2, és mindig legyen fájl a Queue 3 esetében is.
Ez lenne a fő cél, mert így kb ramdisken is futtathatnám, meg nem kellene sok SSD tárhely. Továbbá mindig is akartam látni egy ilyen működést, tehát ez is egy szempont, hogy valami ilyesmi megvalósuljon, mert érdekel.
Egy 8 magos gépen futtatnám, de lehet egy 4 magos gépet is bevonnék, ha megoldható, például megosztott mappán keresztül kommunikálna a processzekkel. Az külön történet, hogy hány processz fogja kihajtani a gépet teljesen, meg hogy mi lesz a szűk keresztmetszet.
Az (el)várt működés:
Elindul, majd elsőnek csak a Queue 1 fut, amíg nem lesz 100 legenerált kombináció.
Amint van 100, akkor a Queue 2 is elkezd működni, elkezdi az 1. legenerált fájlból az M változatot elkészíteni.
Amint van 100, vagy végülis ha már 1 is van az M változatból, akkor elkezdheti az elemző kielemezni azt. Azért írtam 100 M változatot, hogy az elemző is tudjon futni folyamatosan, de hát ezt majd látni kell, mi mennyi idő, most én sem tudom, mi fog sok időt igénybe venni.
Így leírva hülyeség ez a 100 fájl kikötés a Queue 1 és Queue 2 esetén, mert ha már 1 fájlból is tud M változatot generálni, elindulhatna. Csak azért írtam, mert azt hittem, ezzel garantálható, hogy minden a leggyorsabban halad és semmi nem várakozik.
Ha korlátlan tárhelyen és számítási kapacitásom lenne, akkor:
Legenerálnám az N elemeket.
Majd abból az N*M kombinációt.
Majd kielemezné a program, de ezt nem tudom megoldani, mert nagyságrendekkel nagyobb helyet igényelne, mint amit megoldható.
Itt az is nagy kérdés, hogyan, mi módon tároljam, hol tartok.
Ha mindig lemezre írnám, akkor lassú lenne.
Valahogy x percenként leírt állapot elég lenne.
Mysqlt erre használni szerintem nagy lassulást okozna. Nem használnék adattáblákat erre.
Ha a program egy txt állományba mentett paramétereket dolgozna fel, és millió soros lenne a txt állomány, az úgy nekem jó lenne, csak tudni kellene, hol tartok.
Az elemző program meg mindent el tud végezni, bár ezt még be kell fejeznem. Hogy törli a fájlt ha nem jó és elrakja az adatatokat mondjuk egy txt logba, 1 sor 1 lehetőség.
Itt Nosql még szebb lehetne, ha ebbe loggolna, de nem használtam még ilyeneket, főleg nem Windows 10en. Végülis később is át tudom alakitani a txt logot, ha kell valami komolyabb elemzés, vagy eleve több adatot loggolok.
Mindenki máshogy készül a választásra, én inkább elterelem a figyelmem. :)
64 bites PHP 8.0 alapokon vagy 7.4, ezen szeretném ezt megvalósítani, ezt ami hívogatná paraméterekkel a programokat. Jó lenne, ha lenne kész ilyesmire alkalmas framework, class, vagy bármi. Tudnátok ajánlani valamilyen kész, vagy félkész megoldást erre? Biztos van ilyesmi készen, csak én nem találtam még meg.
Én nem multi threadben gondolkodom, nem kell, hogy egy Php program önmagán belül legyen multitask. Sima Phpt használnék. Thread safe maradhat, és simán exec lenne a külső program hívása, majd a visszatérő kódból lehetne tudni, hogy sikeres volt vagy sem, meg létrehött-e a paraméterben megadott file vagy sem. Ha igen, akkor oké volt a process futtatás, az adott task sikeresen lefutott.
Esetleg valamilyen kész open source alkalmazást paramétereznék be erre, ha már van ilyen, ha nem sikerülne megírni vagy találni erre valamit. Tudom, C nyelven kellene ezt írni, assembly betétekkel, de hát az nem reális számomra.