Class/Object

org.querki.requester

RequestM

Related Docs: object RequestM | package requester

Permalink

class RequestM[T] extends AnyRef

The request "monad". It's actually a bit nasty, in that it's mutable, but by and large this behaves the way you expect a monad to work. In particular, it works with for comprehensions, allowing you to compose requests much the way you normally do Futures. But since it is mutable, it should never be used outside the context of an Actor.

Linear Supertypes
AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. RequestM
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Instance Constructors

  1. new RequestM(enclosing: FullName, method: Name, file: File, line: Line)

    Permalink

Value Members

  1. final def !=(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  4. final def asInstanceOf[T0]: T0

    Permalink
    Definition Classes
    Any
  5. def clone(): AnyRef

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  6. val enclosing: FullName

    Permalink
  7. final def eq(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  8. def equals(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  9. val file: File

    Permalink
  10. def filter(p: (T) ⇒ Boolean)(implicit enclosing: FullName, file: File, line: Line): RequestM[T]

    Permalink
  11. def finalize(): Unit

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  12. def flatMap[U](handler: (T) ⇒ RequestM[U])(implicit enclosing: FullName, file: File, line: Line): RequestM[U]

    Permalink

    The central flatMap() operation, which as in any Monad is key to composing these things together.

    The central flatMap() operation, which as in any Monad is key to composing these things together.

    flatMap() is a bit tricky. The problem we have is that we need to return a RequestM *synchronously* from flatMap, so that higher-level code can compose on it. But the *real* RequestM being returned from handler won't come into existence until some indefinite time in the future. So we need to create a new one right now, and when the real one comes into existence, link its success to that of the one we're returning here.

    The initial version of this was beautiful, elegant, and caused stack overflows if you nested flatMaps more than a couple thousand levels deep. (Which, yes, we occasionally do at Querki.) The issue comes during "unwinding" time, when the innermost RequestM finally gets set to a value. The original version had it then call resolve() on the one that contained it, which called resolve() on its parent, and so on, until we finally blew the stack.

    So instead, flatMap builds an ugly but practical linked list of RequestM's, with each one essentially pointing to the one above it. We still call resolve() at each level, but those are *not* recursive; instead, we walk up the flatMap chain *tail*-recursively, resolving each node along the way. It's a bit less elegant, but doesn't cause the JVM to have conniptions.

  13. def foreach(handler: (T) ⇒ Unit): Unit

    Permalink
  14. final def getClass(): Class[_]

    Permalink
    Definition Classes
    AnyRef → Any
  15. def handleSucc(handler: Function1[T, _]): Unit

    Permalink
  16. def hashCode(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  17. var higherLevel: Option[RequestM[T]]

    Permalink

    Build up a chain of RequestM's, from lower levels to higher, so that we can unwind results iteratively instead of through the callbacks.

    Build up a chain of RequestM's, from lower levels to higher, so that we can unwind results iteratively instead of through the callbacks.

    This is rather ugly, but necessary. The original design did the unwinding completely cleanly, with each inner RequestM propagating its result by calling resolve() on the level above it. But that turned out to cause stack overflow crashes when you got to ~2000 levels of flatMap(). So we need a mechanism that can be handled iteratively (well, tail-recursively) instead.

    Attributes
    protected
  18. final def isInstanceOf[T0]: Boolean

    Permalink
    Definition Classes
    Any
  19. val line: Line

    Permalink
  20. def map[U](handler: (T) ⇒ U)(implicit enclosing: FullName, file: File, line: Line): RequestM[U]

    Permalink
  21. val method: Name

    Permalink
  22. final def ne(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  23. final def notify(): Unit

    Permalink
    Definition Classes
    AnyRef
  24. final def notifyAll(): Unit

    Permalink
    Definition Classes
    AnyRef
  25. def onComplete[U](handler: (Try[T]) ⇒ U): Unit

    Permalink
  26. def recover[U >: T](pf: PartialFunction[Throwable, U]): RequestM[U]

    Permalink
  27. def recoverWith[U >: T](pf: PartialFunction[Throwable, RequestM[U]]): RequestM[U]

    Permalink
  28. def resolve(v: Try[T], startUnwind: Boolean = true): Unit

    Permalink

    Set the value for this RequestM, and run through its dependency chain.

    Set the value for this RequestM, and run through its dependency chain.

    You should *not* normally call this yourself -- it is mainly for internal use. Call this only when you have obtained a RequestM through prep(), and need to finish it up, usually because you have to work around some other concurrency construct. (Such as PersistentActor's persist() call.)

    You should ignore the startUnwind flag, which is for internal use only.

  29. def setHigherLevel(higher: RequestM[T]): Unit

    Permalink
    Attributes
    protected
  30. final def synchronized[T0](arg0: ⇒ T0): T0

    Permalink
    Definition Classes
    AnyRef
  31. def toString(): String

    Permalink
    Definition Classes
    AnyRef → Any
  32. final def wait(): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  33. final def wait(arg0: Long, arg1: Int): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  34. final def wait(arg0: Long): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  35. def withFilter(p: (T) ⇒ Boolean): RequestM[T]

    Permalink

Inherited from AnyRef

Inherited from Any

Ungrouped