Ez a cikk a csővezeték tervezési minta megvalósításának különböző módjait mutatja be az alapoktól kezdve a bonyolultabb megoldásokig.
A csővezeték minta
A csővezeték minta egy olyan szoftver tervezési minta, amely lehetővé teszi műveletek sorozatának felépítését és végrehajtását.
Ezt a mintát célszerű a plugin mintával együtt használni, hogy az alkalmazás indításakor dinamikusan felépítsük a csővezetéket.
Sorozat
A csővezeték legalapvetőbb megvalósítása egy egyszerű műveletsorozat lenne.
A művelet interfésze meghívható az adatok feldolgozásához.
A csővezeték az egyes műveleteket egyenként dolgozza fel. A csővezeték osztály is implementálja az IOperation interfészt, így ezek kombinálhatók.
A műveletet meg lehet írni egy dedikált osztályban.
Vagy egy wrapper segítségével automatikusan létrehozhatunk egy műveletet egy lambdából.
A csővezeték műveleteit a csővezeték meghívása előtt regisztrálni kell.
Kapcsoló
A csővezetékhez elsőként egy kapcsolót kell hozzáadni.
Minden művelet az eredményt adja vissza : sikertelen vagy sikeres.
Ha egy művelet sikertelen, a csővezeték végrehajtásának le kell állnia.
Aszinkron
Egy másik követelmény lehet egy olyan csővezeték, amely képes kezelni az aszinkron műveleteket.
Minden műveletnek most meg kell hívnia a következő műveletet a csővezetékben, miután befejezte az adatok feldolgozását.
A csővezeték egy kicsit összetettebb, mert egy új művelet regisztrálásakor be kell állítani a következő műveletet. Egy másik megoldás a builder használata.
Ez a művelet aszinkron, és egy dedikált szálban fut, amikor az idő lejár, meghívja a következő műveletet, hogy folytassa a pipeline-t.
A generikus művelet egyaránt használható egyszerű művelettel, vagy beépített megszakítót használ, ha függvényt használ.
Ez az egyszerű példa az általunk implementált funkciók közül többet is használ.
Most már tudja, hogyan teheti a pipeline-t aszinkronossá !
Még jobb lenne, ha lenne egy másik callback az előző művelethez, hogy az eredmény ellenáramban menjen végig a pipeline-on.
Plugin
A pipeline design patter használatának fő oka gyakran az a követelmény, hogy olyan pluginokat tudjunk hozzáadni, amelyek vagy műveleteket csatolnak egy meglévő pipeline-hoz, vagy egy műveletet akasztanak be annak közepébe.
A pipeline valóban alapvető, de ezúttal a műveletek exponálva vannak.
Vegyünk egy egyszerű alkalmazást egy pipeline-val, amely csak a 3 lépést jeleníti meg a konzolon. Ez az alkalmazás is támogatja a csővezetéket módosító pluginokat.
Az első plugin egy másik műveletet fog beakasztani a csővezeték második résébe.
A második plugin egy új műveletet fog csatolni a csővezeték végére.
Az alkalmazás és a pluginok összeálltak, meg tudjuk hívni a pipeline-t.
Batch
Egy másik hasznos funkció, hogy az egyes tételek helyett kötegelt adatokat is feldolgozhatunk ugyanabban a pipeline-ban.
A kötegelt csővezeték becsomagol egy csővezetéket, és minden műveletet meghív minden egyes elemen.
Minden elemet becsomagolunk, így megjegyezhetjük a megszakító eredményét.
Ez a művelet ellenőrzi, hogy az egész szám rendelkezik-e a kívánt nagyságrenddel.
A csővezeték egy kötegnyi egész szám nagyságrendjét fogja ellenőrizni.
A csővezeték csak azoknál az elemeknél hívja meg a következő műveletet, amelyek nem hibáztak.
Nagy teljesítményű csővezeték
A csővezeték tervezési minta egy sokkal specifikusabb és teljesítményorientált szoftverarchitektúrára is utalhat.
Egy-egy projekt a csővezetéket a nagy mennyiségű adat feldolgozásának optimalizálására használja úgy, hogy a csővezeték egyes műveleteit egy dedikált szálban futtatja.
Minden szál adatokat fogyaszt és termel egy párhuzamos várólistából, amely pufferként fog működni.
Ezúttal aszinkron műveleteket fogunk használni egy megszakítóval.
Ha a művelet sikeres, akkor meg kell hívnia a következőt, vagy meg kell szakítania, ha sikertelen.
A pipeline úgy van kialakítva, hogy megkerülje a megszakítót. Sikeres vagy sikertelen, mindig folytatja a szülő csővezeték szekvenciáját, és meghívja a következő műveletet.
A forgatókönyv kicsit összetett, ezért nem magyarázok el mindent. Az ötlet az, hogy különböző szálak dolgozzák fel a beérkező megbízásokat. Amikor egy rendelés feldolgozása befejeződik, ellenőrizzük a rendelés állapotát.
Minden rendelésfeldolgozó el van szigetelve egy dedikált szálban, így optimalizálhatjuk az adatok tárolásának módját, és közvetlen memóriaelérésünk van lock használata nélkül.
A fizetési rendelésfeldolgozó az egyetlen szál, amely hozzáférhet a felhasználói egyenlegekhez. Bármilyen egyenleget lekérhet vagy frissíthet anélkül, hogy az egyidejűségi problémákkal foglalkozna.
A pipeline a lehető leggyorsabban dolgozza fel a műveletsort.
Következtetés
A csővezeték tervezési minta nagyon sokféleképpen megvalósítható, az egyszerű parancslánctól a bonyolultabb munkafolyamatig.
Sok funkcióra lehet szükség, mint például a megszakító, az aszinkron vagy a puffer, de legtöbbször akkor szeretnénk csővezetéket használni, ha olyan bővítményeket szeretnénk, amelyek be tudnak akadni a csővezeték végrehajtási folyamába.