The document discusses Iteratees and Enumerators in Play Framework. It provides an overview of the important concepts - Enumerator produces values, Enumeratee transforms values, and Iteratee consumes input. It also summarizes the APIs for Enumerator, Enumeratee and Iteratee, including common patterns for building Iteratees. Links are provided for additional documentation and examples.
1 of 16
Download to read offline
More Related Content
Iteratees/Enumerators in Play
1. ENUMERATOR &> PLAY
|>>>
ITERATEE
PLAY MEETUP HAMBURG, 6.10.2014
MARKUS.KLINK@INO.IO
@JOHEINZ
3. SOME LINKS:
PLAY DOCUMENTATION
(MORE OR LESS INCOMPREHENSIBLE)
HTTP://MANDUBIAN.COM/2012/08/27/UNDERSTANDING-PLAY2-ITERATEES-FOR-NORMAL-HUMANS/
(ADDRESSES SOME OF THE SHORTCOMINGS)
HTTPS://JAZZY.ID.AU/2012/11/06/ITERATEES_FOR_IMPERATIVE_PROGRAMMERS.HTML
(YEAH, MORE INFO)
ACTIVATOR TEMPLATE (SEARCH FOR ITERATEES)
HTTPS://GITHUB.COM/JROPER/PLAY-ITERATEES-EXTRAS
HTTPS://WWW.PLAYFRAMEWORK.COM/DOCUMENTATION/2.3.X/API/SCALA/INDEX.HTML#PLAY.API.LIBS.3
5. REACTIVE STREAMS ARE
TWO WAY, IT'S NOT JUST
YOU, THE STREAM
CONSUMER THAT IS
REACTING TO INPUT, THE
STREAM PRODUCER MUST
REACT TO YOU BEING READY
FOR INPUT. James Roper
7. THE IMPORTANT BITS
ENUMERATOR[A]
PRODUCES VALUES OF TYPE A
MONAD (COMPOSABLE WITH A CONTEXT)
MANY UTILITIES IN COMPANION OBJECT
SMART
!
8. ENUMERATOR API
Enumerator.apply[A](a: A*) : Enumerator[A]
Enumerator.enumerate[A](a: TraversableOnce[A]) : Enumerator[A]
Enumerator.generateM[A](e : => Future[Option[A]]) : Enumerator[A]
ALL THE FLATMAP GOODIES + GIVEN AN ENUMERATOR[E]
|>>[A](i: Iteratee[E, A]): Future[Iteratee[E, A]]
|>>>[A](i: Iteratee[E, A]): Future[A]
&>[To](enumeratee: Enumeratee[E, To]): Enumerator[To]
9. THE IMPORTANT BITS
ENUMERATEE[A,B]
TRANSFORMS VALUES FROM A => B
!
MANY UTILITIES IN COMPANION OBJECT
!
NOT AS DUMP AS I THOUGHT
10. THE IMPORTANT BITS
ITERATEE[A,B]
CONSUMES INPUT ELEMENTS OF TYPE A AND OUTPUTS B
MONAD (COMPOSABLE WITH A CONTEXT)
SUPER SMART
!
!
!
INPUT IS EITHER:
A.EMPTY: INPUT.EMPTY
B.EOF: INPUT.EOF
C.OR CONTAINS AN A: INPUT.EL(A)
!
ITERATEE STATE IS EITHER:
A. DONE CONSUMING WITH A RESULT
B. READY TO CONSUME MORE CONT
C. OR IN ERROR STATE
11. ITERATEE API
ALL THE FLATMAP GOODIES + GIVEN AN ITERATEE[E,A]
run: Future[A]
COMMON PATTERN TO BUILD AN ITERATEE:
def myIteratee(x: AllTheStateINeed,
oForNothing: O) : Iterator[I,O] = Cont {
case Input.EOF => Done(oForNothing, Input.EOF)
case Input.Empty => myIterator(x, oForNothing)
case in@Input(i) => // be done with o || change state and recurse
// create an Error with Error(message, in)
!
12. HINT
WHEN USING DONE,
ALWAYS SPECIFY THE
NEXT INPUT EXPLICITLY
(DEFAULTS TO
INPUT.EMPTY)
14. ENUMERATEE API
THINK OF AN ENUMERATOR AS A KIND OF
TRANSFORMER, ADAPTER AND COLLECTION:
TAKE, TAKEWHILE,
GROUPED,
DROP, DROPWHILE,
FILTER, FILTERNOT, MAP,
15. val processElement: Iteratee[Byte, Element] = for {
_ <- findLeftBrace
string <- consumeUntilRightBrace
element <- {
safeParse(string) match {
case Success(element) => Done[Byte, Element](element)
case Failure(_) => Error[Byte](s"$string not a valid element", Input.EOF)
}
}
} yield element
COMPOSE
ITERATEES & ENUMERATORS
USING FOR
COMPREHENSIONS