Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/meh/reagent
You need more reagents to conjure this server.
https://github.com/meh/reagent
Last synced: 4 days ago
JSON representation
You need more reagents to conjure this server.
- Host: GitHub
- URL: https://github.com/meh/reagent
- Owner: meh
- Created: 2013-09-07T16:30:48.000Z (about 11 years ago)
- Default Branch: master
- Last Pushed: 2017-07-06T11:34:08.000Z (over 7 years ago)
- Last Synced: 2024-10-25T06:38:11.234Z (11 days ago)
- Language: Elixir
- Size: 60.5 KB
- Stars: 93
- Watchers: 5
- Forks: 10
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- freaking_awesome_elixir - Elixir - reagent is a socket acceptor pool for Elixir. (Networking)
- fucking-awesome-elixir - reagent - reagent is a socket acceptor pool for Elixir. (Networking)
- awesome-elixir - reagent - reagent is a socket acceptor pool for Elixir. (Networking)
README
reagent - socket acceptor pool
==============================
**reagent** is a socket acceptor pool for Elixir that leverages the
[socket](https://github.com/meh/elixir-socket) library and its protocols to
provide an easy way to implement servers.Getting started
---------------
To define a reagent you first have to define a module using the reagent
behaviour. This will define some basic functions you can extend and other
helpers on the module and will make it startable as a reagent.```elixir
defmodule Test do
use Reagent.Behaviour
end
```When you want to start a server running the defined reagent, you have to call
`Reagent.start`. It takes as first parameter the module implementing the
behaviour and as second parameter a listener descriptor.Listener descriptors contain the definition of the listener, including port,
whether they're secure or not, other socket options and starting environment.Reagent behaviour
-----------------
A reagent to do anything useful has to either implement `handle/1` or `start/1`.`handle/1` is called by the default `start/1` and it gets called as a
replacement for the acceptor process. It gets called with a
`Reagent.Connection` record.This is usually useful to implement simple protocols when you don't need a full
blown `gen_server` or similar to handle a connection.If you want more complex connection handling you can define `start/1`, it gets
called with a `Reagent.Connection` record as well and must return `{ :ok, pid
}` or `{ :error, reason }`. The returned process will be made owner of the
socket and be used as reference for the connection itself.You can also define `accept/1` which gets called with the `Reagent.Listener`
and allows you more fine grained socket acception.Simple example
--------------
```elixir
defmodule Echo do
use Reagentdef handle(conn) do
case conn |> Socket.Stream.recv! do
nil ->
:closeddata ->
conn |> Socket.Stream.send! datahandle(conn)
end
end
end
```This is a simple implementation of an echo server.
To start it on port 8080 just run `Reagent.start Echo, port: 8080`.
Complex example
---------------
```elixir
defmodule Echo do
use Reagentdef start(connection) do
GenServer.start __MODULE__, connection, []
enduse GenServer
def init(connection) do
{ :ok, connection }
end# this message is sent when the socket has been completely accepted and the
# process has been made owner of the socket, you don't need to wait for it
# when implementing handle because it's internally handled
def handle_info({ Reagent, :ack }, connection) do
connection |> Socket.active!{ :noreply, connection }
enddef handle_info({ :tcp, _, data }, connection) do
connection |> Socket.Stream.send! data{ :noreply, connection }
enddef handle_info({ :tcp_closed, _ }, connection) do
{ :stop, :normal, connection }
end
end
```This is the implementation of a full-blown `gen_server` based echo server
(which is obviously overkill).As with the simple example you just start it with `Reagent.start Echo, port:
8080`.