Tethys

Tethys was the Titan goddess of the primal font of fresh water which nourishes the earth... feeding her children's springs with the waters of Okeanos drawn through subterranean acquifers.

A networking library that guides and crafts the streams of information flowing through the modern world. Aiding the technological waters drawn from lakes, rivers, and rains as they move towards the world's oceans.

Concepts

Pools

Pools are places where data is stored. For example, a StillPool is a Pool which just appends any data it receives into an in-memory list.

Flows

Flows are entities through which data may move. For example, a DispersedFlow can act as a round-robin load balancer between multiple flows.

Springs

Springs are entities that may produce data. For example, a UdpSpring can connect to a port and any data sent to that port will be pushed to a connected flow.

Locks

Locks are bi-directional Flows, where the direction you are moving applies different transforms to the data. For example, a MsgPackLock, when moving one way will pack data moving through it via MessagePack. The other direction will unpack the data.

Usage Examples

More examples can be found in the unit tests.

  test "round-robins data evenly across destinations" do
    pool_a = StillPool.seed!()
    pool_b = StillPool.seed!()

    DispersedFlow.craft!([pool_a, pool_b])
    |> Flow.receive("Data A")
    |> Flow.receive("Data B")
    |> Flow.receive("Data C")
    |> Flow.receive("Data D")
    |> Flow.receive("Data E")
    |> Flow.receive("Data F")

    pool_a |> Pool.drain(self())
    assert_receive {:drip, _, "Data A"}, 50
    assert_receive {:drip, _, "Data C"}, 50
    assert_receive {:drip, _, "Data E"}, 50

    pool_b |> Pool.drain(self())
    assert_receive {:drip, _, "Data B"}, 50
    assert_receive {:drip, _, "Data D"}, 50
    assert_receive {:drip, _, "Data F"}, 50
  end

  test "sends (pumps) UDP messages that flow into it" do
    pool_a = StillPool.seed!() |> Pool.leak(self())
    pool_b = StillPool.seed!() |> Pool.leak(self())

    UdpSpring.seed!(%{address: %{port: 5555}})
    |> Spring.flow(pool_a)

    UdpSpring.seed!(%{address: %{port: 6666}})
    |> Spring.flow(pool_b)

    UdpSpring.seed!(%{address: %{port: 4444}})
    |> UdpSpring.pumps([
      {{127, 0, 0, 1}, 5555},
      {{127, 0, 0, 1}, 6666}
    ])
    |> Flow.receive("Broadcast to both")

    assert_receive {:drip, ^pool_a, "Broadcast to both"}, 50
    assert_receive {:drip, ^pool_b, "Broadcast to both"}, 50
  end

Installation

If available in Hex, the package can be installed by adding tethys to your list of dependencies in mix.exs:

def deps do
  [
    {:tethys, "~> 0.1.0"}
  ]
end

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/tethys.