Couplings

Couplings are stream graph components with one input, one output and no internal transformation logic. They are typically used to manually connect two ports of a stream graph that cannot be otherwise connected via the streaming DSL, e.g. for creating cycles.

A Coupling

A Coupling is essentially nothing but a Drain and Spout of the same element type that are directly connected to each other internally. You can use the two sides of the Coupling independently at arbitrary points in a stream graph definition to create connections where you need them.

Here is an example of a stream that contains a cycle and therefore requires the use of a Coupling:

import scala.concurrent.Future
import swave.core._

implicit val env = StreamEnv()

def fibonacciNumbers = {
  val c = Coupling[Int]
  Spout(0, 1)
    .concat(c.out)
    .fanOutBroadcast(eagerCancel = true)
      .sub.buffer(2, Buffer.RequestStrategy.Always).sliding(2).map(_.sum).to(c.in)
      .subContinue
}

val result: Future[List[Int]] =
  fibonacciNumbers
    .take(8)
    .drainToList(limit = 100)

result.value.get.get shouldEqual List(0, 1, 1, 2, 3, 5, 8, 13)

(For an in-depth discussion of this stream setup check out the Fibonacci Example!)