reverl - REVerse proxy in ERLang
Created the reverl project on Google Code. Reverl is reverse proxy, load balancer and HTTPS front-end for Web server(s), implemented in Erlang.
Before to start the real coding, I needed a more general proxy(gateway) behaviour.
What exactly is proxy (or gateway)? It's the middle-man between the client and a set of backend service providers, the guy who get the requests, resend them to some backend, get the response for that backend and return it back to the client. The interesting part is the choice of backend with possible load balancing and tracking backends failover. In general the proxy(gateway) give you High Availabity (HA) of the provided services.
So on the question. The first code approximation:
-module(gproxy0). -export([start_be/1,start_gw/1,change_be/2,rpc/2]). %% start the server (backend) start_be(Fun) -> spawn(fun() -> loop(Fun) end). %% start the proxy (frontend) start_gw(Backend) -> spawn(fun() -> gloop(Backend) end). %% Pid can be gateway or server rpc(Pid, Q) -> Pid ! {self(), Q}, receive {Pid, Reply} -> Reply end. %% change the backend , send to the GATEWAY change_be(Gw,Backend) -> Gw ! {be_change,Backend}. %% server (backend) loop loop(Fun) -> receive %% direct request {From, X} -> From ! {self(), Fun(X)}, loop(Fun); %% request via gateway {Gw, From, X} -> Gw ! {From, ok, Fun(X)}, loop(Fun) end. %% gateway (frontend) loop gloop(Backend) -> receive {be_change,Backend1} -> gloop(Backend1); {Client, X} -> Backend ! {self(), Client, X}, gloop(Backend); {Client, ok, X} -> Client ! {self(), X}, gloop(Backend) end.
Usage
$ erl 1> c(gproxy0). {ok,gproxy0} 2> F1=fun(X) -> 2*X end. % provided service #Fun<erl_eval.6.56006484> 3> B1 = gproxy0:start_be(F1). % start the backend <0.38.0> 4> gproxy0:rpc(B1,21). % service request to the backend 42 5> G=gproxy0:start_gw(B1). % create the gateway with one backend <0.41.0> 6> gproxy0:rpc(G,21). % service request to the gateway 42 7> B2=gproxy0:start_be(fun(X) -> 3*X end). % new backend <0.44.0> 8> gproxy0:change_be(G,B2). % change the backend {be_change,<0.44.0>} 9> gproxy0:rpc(G,21). 63
More sophisticated code versions (changing service code on the fly, handling errors etc.) are available for download:
- gproxy.erl -- General gateway behaviour
- gproxy1.erl -- General gateway behaviour with some errors protection
- gproxy2.erl -- Gateway behaviour with simple round robin between backends
Stay tuned...