Play! Iteratees pro realtime streamování dat - 2. část
V druhé části miniseriálu o realtime streamování dat v Play! frameworku se podíváme blíže na adaptování (transformace) dat a iteratees si demonstrujeme na jednoduchém příkladu streamování textu.
Enumeratees – adaptování produkovaných dat
Enumeratee[From, To] je adaptérem streamu produkujícího data typu "From" na stream produkující data typu "To". Enumeratee může kromě organizace (typu) dat pozměnit např. i způsob bufferování dat (změnit počet položek v produkované skupině dat), nebo vynechat/přidat části produkovaných dat.
Enumerátory lze pomocí enumeratees adaptovat tak, aby mohly být použity pro produkování dat i pro iteratee, která přijímají jiný typ dat. Anebo iteratee lze pomocí enumeratees transformovat na iteratee jiného vyhovujícího typu, aby bylo schopné spolupracovat s určitým enumerátorem (voláním myEnumeratee.transform(myIteratee), resp. použitím symbolu &>>).
V Play! můžeme psát vlastní adaptéry a transformátory produkovaných dat nebo použít některé základní, které jsou součástí frameworku. Instance Enumeratees lze vytvářet pomocí factory metod:
- Enumeratee.map[From] – přijímá funkci pro převod instance typu From na instanci typu To, kterou je třeba implementovat.
- Enumeratee.mapInput[From] – přijímá funkci pro převod instance typu Input[From] na instanci typu Input[To] (tj. trochu obecnější případ předchozí metody map).
- Enumeratee.filter(predicate) – vrací Enumeratee, které je schopné filtrovat příchozí skupiny dat podle daného predikátu. Existují i další podobné factory metody založené na predikátech.
Příklad adaptování konzumování celých čísel na konzumování řetězců (metodou transform, neboli &>>):
Zadaptované iteratee s sebou nese i původní (vnitřní) iteratee, které z něj můžeme získat zpět, pokud to potřebujeme.
Adaptování produkování řetězců na produkování celých čísel (metodou through, neboli &> na enumerátoru) - je použito stejné enumeratee:
Při implementaci adaptování vstupního typu dat na výstupní typ lze s výhodou použít pattern matching, pokud transportujeme instance z hierarchie typů (From je společným předkem přenášených dat – nějakou case class).
Instance enumeratees lze zřetězit dohromady pomocí metody compose (nebo ><>) a poté je společně použít k adaptaci iteratee nebo enumerátoru.
Ukázka streamování dat ze serveru a jejich adaptace
Na GitHubu se můžete podívat na jednoduchou ukázkovou aplikaci, která streamuje ze serveru na klienta (do web browseru) po řádcích známou "klasiku" - Shakespearova Hamleta. Web browser iniciuje streamování pomocí WebSocketu, server pak po vyhrazeném web socketu streamuje jednotlivé řádky pomocí enumerátorů a všudypřítomného iteratees API a na ukázku se provádí i lehká transformace dat pomocí enumeratees.
Příklad jsem nasazoval na Heroku cloud. Scala a Play! framework (v první i druhé verzi) jsou podporovány, ale Heroku stále nepodporuje WebSockety. Zdrojové kódy jsou nicméně dostupné na GitHubu. To nejdůležitější se děje ve třídách HamletStream a IndexController. JavaScript v šabloně index.scala.html iniciuje komunikaci přes WebSocket.
Kam dále?
Hlubší popis Iteratees API a více příkladů naleznete v oficiální dokumentaci Play! frameworku a článku Understanding Play2 Iteratees for Normal Humans. Pěkný příklad realtime streamování audia (alá internetové rádio) na blogu @GreWeb.
Play! Iteratees pro realtime streamování dat - 1. část