Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kbrw/exos
Exos is a simple Port Wrapper : a GenServer which forwards cast and call to a linked Port.
https://github.com/kbrw/exos
clojure elixir nodejs python
Last synced: about 1 month ago
JSON representation
Exos is a simple Port Wrapper : a GenServer which forwards cast and call to a linked Port.
- Host: GitHub
- URL: https://github.com/kbrw/exos
- Owner: kbrw
- Created: 2014-09-16T10:26:57.000Z (about 10 years ago)
- Default Branch: master
- Last Pushed: 2021-10-29T09:55:29.000Z (about 3 years ago)
- Last Synced: 2024-10-31T15:02:29.317Z (about 1 month ago)
- Topics: clojure, elixir, nodejs, python
- Language: Elixir
- Homepage:
- Size: 18.6 KB
- Stars: 78
- Watchers: 7
- Forks: 7
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- freaking_awesome_elixir - Elixir - A Port Wrapper which forwards cast and call to a linked Port. (Actors)
- fucking-awesome-elixir - exos - A Port Wrapper which forwards cast and call to a linked Port. (Actors)
- beamtoolbox - [erl
README
Exos
====Exos is a simple Port Wrapper : a GenServer which forwards cast and call to a
linked Port. Requests and responses are converted using binary erlang term
external representation.You can use it to create a GenServer for Python, Clojure, NodeJS with :
- [clojure-erlastic](http://github.com/awetzel/clojure-erlastic)
- [python-erlastic](http://github.com/awetzel/python-erlastic)
- [node-erlastic](http://github.com/kbrw/node_erlastic)## Launching a Clojure/Python/NodeJS GenServer and use it in Elixir ##
Usage : `Exos.Proc.start_link` (see function documentation), then the resulting
process is a GenServer where cast and call are binary encoded through stdio to
the underlying process. If the GenServer receive messages outside of a call, an
anonymous function can be attached to be called on each message.See `test/port_example.exs` for a reference implementation of a server that can
be launched in a port with `Exos.Proc`, and `test/exos_test.exs` for its use.
`clojure/python/node_erlastic` projects can be used to launch a
java/python/javascript GenServer.See above an example of an account manager server developped in
python/nodejs/clojure.```elixir
defmodule Account do
def cmd do
case Application.get_env(:account_impl) do
:python-> "venv/bin/python -u account.py"
:node-> "node account.js"
:clojure-> "java -cp 'target/*' clojure.main account.clj"
end
end
def start_link(ini), do: Exos.Proc.start_link(cmd,ini,[cd: "#{:code.priv_dir(:myproj)}/account"],name: __MODULE__)
def add(v), do: GenServer.cast(__MODULE__,{:add,v})
def rem(v), do: GenServer.cast(__MODULE__,{:rem,v})
def get, do: GenServer.call(__MODULE__,:get,:infinity)
enddefmodule MyProj.App do
use Application
def start(_,_), do: MyProj.App.Sup.start_linkdefmodule Sup do
use Supervisor
def start_link, do: Supervisor.start_link(__MODULE__,[])
def init([]), do: supervise([
worker(Account,[0])
], strategy: :one_for_one)
end
end
```> vim mix.exs
```elixir
def application do
[mod: { MyProj.App, [] }]
end
```Finally just implement your account server in any language as describe below,
and use it as a standard GenServer.> iex -S mix
```elixir
Account.add(5)
Account.rem(1)
4 == Account.get
```## Account Server Implementation in clojure ##
```bash
mix new myproj
cd myproj ; mkdir -p priv/account; cd priv/account
vim project.clj
``````clojure
(defproject account "0.0.1"
:dependencies [[clojure-erlastic "0.2.3"]
[org.clojure/core.match "0.2.1"]])
``````bash
lein uberjar
vim account.clj
``````clojure
(require '[clojure-erlastic.core :refer [run-server]])
(use '[clojure.core.match :only (match)])
(run-server
(fn [term count] (match term
[:add n] [:noreply (+ count n)]
[:rem n] [:noreply (- count n)]
:get [:reply count count])))
```## Account Server Implementation in Python >3.4 ##
```bash
mix new myproj
cd myproj ; mkdir -p priv/account; cd priv/account
echo "git://github.com/awetzel/python-erlastic.git#egg=erlastic" > requirements.txt
pyvenv venv
./venv/bin/pip install -r requirements.txt
vim account.py
``````python
mailbox,port = port_connection()
account = next(mailbox) #first msg is initial state
for req in mailbox:
if req == "get": port.send(account)
else:
(op,amount) = req
account = (account+amount) if op=="add" else (account-amount)
```## Account Server Implementation in NodeJS ##
```bash
mix new myproj
cd myproj ; mkdir -p priv/account; cd priv/account
npm init
npm install node_erlastic --save
vim account.js
``````javascript
require('node_erlastic').server(function(term,from,current_amount,done){
if (term == "get") return done("reply",current_amount);
if (term[0] == "add") return done("noreply",current_amount+term[1]);
if (term[0] == "rem") return done("noreply",current_amount-term[1]);
throw new Error("unexpected request")
});
```# CONTRIBUTING
Hi, and thank you for wanting to contribute.
Please refer to the centralized informations available at: https://github.com/kbrw#contributing