Coder Social home page Coder Social logo

exos's Introduction

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 :

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.

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)
end

defmodule MyProj.App do
  use Application
  def start(_,_), do: MyProj.App.Sup.start_link

  defmodule 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

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

Account.add(5)
Account.rem(1)
4 == Account.get

Account Server Implementation in clojure

mix new myproj
cd myproj ; mkdir -p priv/account; cd priv/account
vim project.clj
(defproject account "0.0.1" 
  :dependencies [[clojure-erlastic "0.2.3"]
                 [org.clojure/core.match "0.2.1"]])
lein uberjar
vim account.clj
(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

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
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

mix new myproj
cd myproj ; mkdir -p priv/account; cd priv/account
npm init
npm install node_erlastic --save
vim account.js
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

exos's People

Contributors

awetzel avatar shakadak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

exos's Issues

Does exos retain state for per request?

For a phoenix project, I have defined a GenServer implementation using exos in my lib/projectname folder in order to connect to an external program. One of my controllers in web/controller sends it data and gets a reply synchronously. However, I am not sure whether the GenServer is being killed after each request and I am worried about race conditions in production. According to this, the information in web/ is reloaded per request. I don't have a good way of testing whether the GenServer is being killed since I am calling it in a similar manner with the example applications i.e. define it in one part of the module and call it via an api: 4==Account.get() . Another question is, is it logical to spawn a GenServer per phoenix request? Is it simpler to use something like e.g. Porcelain to interface with external programs if all the GenServer does is to handle synchronous calls etc.?

hex version is not up to date

Published version on hex is 1.0.1 which raise warnings when compiling with elixir 1.4, while master branch not.

-> hex version should be updated

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.