{"id":13508723,"url":"https://github.com/meh/reagent","last_synced_at":"2025-05-08T04:35:37.245Z","repository":{"id":57541044,"uuid":"12667801","full_name":"meh/reagent","owner":"meh","description":"You need more reagents to conjure this server.","archived":false,"fork":false,"pushed_at":"2017-07-06T11:34:08.000Z","size":62,"stargazers_count":92,"open_issues_count":2,"forks_count":10,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-12-19T04:06:33.981Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-09-07T16:30:48.000Z","updated_at":"2024-12-11T22:03:03.000Z","dependencies_parsed_at":"2022-09-17T23:22:50.829Z","dependency_job_id":null,"html_url":"https://github.com/meh/reagent","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meh%2Freagent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meh%2Freagent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meh%2Freagent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meh%2Freagent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meh","download_url":"https://codeload.github.com/meh/reagent/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231474812,"owners_count":18382160,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T02:00:57.527Z","updated_at":"2024-12-27T11:14:05.981Z","avatar_url":"https://github.com/meh.png","language":"Elixir","readme":"reagent - socket acceptor pool\n==============================\n**reagent** is a socket acceptor pool for Elixir that leverages the\n[socket](https://github.com/meh/elixir-socket) library and its protocols to\nprovide an easy way to implement servers.\n\nGetting started\n---------------\nTo define a reagent you first have to define a module using the reagent\nbehaviour. This will define some basic functions you can extend and other\nhelpers on the module and will make it startable as a reagent.\n\n```elixir\ndefmodule Test do\n  use Reagent.Behaviour\nend\n```\n\nWhen you want to start a server running the defined reagent, you have to call\n`Reagent.start`. It takes as first parameter the module implementing the\nbehaviour and as second parameter a listener descriptor.\n\nListener descriptors contain the definition of the listener, including port,\nwhether they're secure or not, other socket options and starting environment.\n\nReagent behaviour\n-----------------\nA reagent to do anything useful has to either implement `handle/1` or `start/1`.\n\n`handle/1` is called by the default `start/1` and it gets called as a\nreplacement for the acceptor process. It gets called with a\n`Reagent.Connection` record.\n\nThis is usually useful to implement simple protocols when you don't need a full\nblown `gen_server` or similar to handle a connection.\n\nIf you want more complex connection handling you can define `start/1`, it gets\ncalled with a `Reagent.Connection` record as well and must return `{ :ok, pid\n}` or `{ :error, reason }`. The returned process will be made owner of the\nsocket and be used as reference for the connection itself.\n\nYou can also define `accept/1` which gets called with the `Reagent.Listener`\nand allows you more fine grained socket acception.\n\nSimple example\n--------------\n```elixir\ndefmodule Echo do\n  use Reagent\n\n  def handle(conn) do\n    case conn |\u003e Socket.Stream.recv! do\n      nil -\u003e\n        :closed\n\n      data -\u003e\n        conn |\u003e Socket.Stream.send! data\n\n        handle(conn)\n    end\n  end\nend\n```\n\nThis is a simple implementation of an echo server.\n\nTo start it on port 8080 just run `Reagent.start Echo, port: 8080`.\n\nComplex example\n---------------\n```elixir\ndefmodule Echo do\n  use Reagent\n\n  def start(connection) do\n    GenServer.start __MODULE__, connection, []\n  end\n\n  use GenServer\n\n  def init(connection) do\n    { :ok, connection }\n  end\n\n  # this message is sent when the socket has been completely accepted and the\n  # process has been made owner of the socket, you don't need to wait for it\n  # when implementing handle because it's internally handled\n  def handle_info({ Reagent, :ack }, connection) do\n    connection |\u003e Socket.active!\n\n    { :noreply, connection }\n  end\n\n  def handle_info({ :tcp, _, data }, connection) do\n    connection |\u003e Socket.Stream.send! data\n\n    { :noreply, connection }\n  end\n\n  def handle_info({ :tcp_closed, _ }, connection) do\n    { :stop, :normal, connection }\n  end\nend\n```\n\nThis is the implementation of a full-blown `gen_server` based echo server\n(which is obviously overkill).\n\nAs with the simple example you just start it with `Reagent.start Echo, port:\n8080`.\n","funding_links":[],"categories":["Networking"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeh%2Freagent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeh%2Freagent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeh%2Freagent/lists"}