<div dir="ltr">On 16 December 2015 at 20:25, Hugo Mills <span dir="ltr"><<a href="mailto:hugo@carfax.org.uk" target="_blank">hugo@carfax.org.uk</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">   Thanks for the reply.<br>
<div><div class="h5"><br>
On Wed, Dec 16, 2015 at 12:17:50AM +0000, Chandru wrote:<br>
> On 16 December 2015 at 00:10, Hugo Mills <<a href="mailto:hugo@carfax.org.uk">hugo@carfax.org.uk</a>> wrote:<br>
><span style="color:rgb(34,34,34)">> - You can have a global cowboy handler (one module which is used in all</span><br></div></div><span class="">
> your backend erlang nodes) which provides internal routing for all your<br>
> services. At its most basic form, routing in cowboy is redirecting requests<br>
> based on URL to a module. So you just have to make sure this module is<br>
> common across all your erlang nodes, regardless of how you distribute your<br>
> services across nodes.<br>
<br>
</span>   So I make sure that I have a 'common_routing' (or whatever) module<br>
in each service -- do those have their own router (for the internal<br>
routing within each service) in each one?<br></blockquote><div><br></div><div>Your common routing can be put in a separate application. So your list of applications in your .rel file would be something like</div><div>...</div><div>cowboy</div><div>common_routing</div><div>service_1</div><div>service_2</div><div>...</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
   I guess that's something that Loïc's work with Cowboy and RabbitMQ<br>
would help with.<br>
<span class=""><br>
> What am I missing here?<br>
<br>
</span>   It's probably what I'm missing...<br>
<br>
   How do I handle deploying this? I really don't want to be building<br>
a different release for each configuration, so how do I enable/disable<br>
the different services in each separate deployment? How do I make sure<br>
that the unused services don't run when the release is run, and don't<br>
have routing entries in the top-level router? (Ideally, not shipping<br>
the unused code at all, but if I'm building a single release, I guess<br>
that's not going to be possible).<br></blockquote><div><br></div><div>One way is to ship the same release with all your services bundled in, but turn services on/off based on configuration. You specify in a common sys.config which nodes should have which services. Ship all your services in each node, and at startup they check if they should be running on the local node. If not, they just stay disabled. Similarly, the common_routing application can check configuration to see which handlers should be activated in each node.</div><div><br></div><div>If you don't want certain services to start at all if they are not supposed to run on a given node, you can develop an application whose sole job is to start other applications. It can examine the configuration and start which ever applications are relevant to the given node. Your release file will then have a specification such as </div><div><br></div><div>...</div><div>{cowboy, "cowboy_version"}</div><div>{common_routing, "common_routing_version"},</div><div>{app_loader, "app_loader_version"},</div><div>{service_1, "service_1_version", load}</div><div><div>{service_2, "service_2_version", load}</div></div><div>...</div><div><br></div><div>This means beam will only load the modules at startup. Your app_loader application on startup can examine its config and start whichever services need to be started. If you do not use the '-embedded' option to al when starting up your node, you can even introduce new applications into the node without restarting it. I used this in production quite successfully in my previous role. It cut the time to introduce new services into production drastically.</div><div><br></div><div>cheers,</div><div>Chandru</div><div> </div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class=""><div class="h5">
> > ><br>
> > > On 15 December 2015 at 23:41, Hugo Mills <<a href="mailto:hugo@carfax.org.uk">hugo@carfax.org.uk</a>> wrote:<br>
> > ><br>
> > > >    I've got a collection of small services, with minimal coupling<br>
> > > > between the back ends of those services (orchestration is done mostly<br>
> > > > client-side). I'd like to put an HTTPS interface in front of each one<br>
> > > > -- say, with cowboy.<br>
> > > ><br>
> > > >    What I'd also like to be able to do, at least in principle, is<br>
> > > > deploy some arbitrary subset of those services on each machine in my<br>
> > > > (comedically-named) server farm. I'd like to be able to do this with<br>
> > > > one TLS configuration, and preferably under a single port.<br>
> > > ><br>
> > > > i.e., access my services through<br>
> > > ><br>
> > > > <a href="https://server.me/service1/." rel="noreferrer" target="_blank">https://server.me/service1/.</a>..<br>
> > > > <a href="https://server.me/service2/." rel="noreferrer" target="_blank">https://server.me/service2/.</a>..<br>
> > > > <a href="https://server.me/service3/." rel="noreferrer" target="_blank">https://server.me/service3/.</a>..<br>
> > > ><br>
> > > >    Now, in python-land, which is largely where I come from, I'd set up<br>
> > > > Apache with mod-wsgi, and deploy each WSGI app to a specific URL<br>
> > > > within the same URL namespace. I'm not quite sure how to do that<br>
> > > > easily with erlang+cowboy, because there seems to be no easy way of<br>
> > > > treating a webapp as a unit within a larger server configuration. I<br>
> > > > keep coming to one of two approaches:<br>
> > > ><br>
> > > > 1) Write each service completely independently (as HTTP), run it on a<br>
> > > >    distinct port, and splice together the URL namespaces through a<br>
> > > >    reverse proxy on a "normal" web server like Apache.<br>
> > > ><br>
> > > > 2) Find some way to automatically write a top-level router for cowboy,<br>
> > > >    for each set of services that I want to deploy to a machine.<br>
> > > ><br>
> > > >    I don't much like option 1, but I like option 2 even less. I guess<br>
> > > > I could write some kind of "top-level" app that, given a bunch of<br>
> > > > webapp modules (via a configuration file of some kind), gets a router<br>
> > > > for each module and transforms those routers into a single router<br>
> > > > config. Does such a thing already exist?<br>
> > > ><br>
> > > >    It all just feels a bit awkward, and I feel like I'm missing<br>
> > > > something. What do other people do to put together this kind of setup?<br>
> > > ><br>
> > > >    Hugo.<br>
> > > ><br>
> ><br>
<br>
--<br>
</div></div><span class=""><font color="#888888">Hugo Mills             | Beware geeks bearing GIFs<br>
hugo@... <a href="http://carfax.org.uk" rel="noreferrer" target="_blank">carfax.org.uk</a> |<br>
<a href="http://carfax.org.uk/" rel="noreferrer" target="_blank">http://carfax.org.uk/</a>  |<br>
PGP: E2AB1DE4          |<br>
</font></span></blockquote></div><br></div></div>