Using UNIX sockets with Erlang

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Using UNIX sockets with Erlang

Jérôme Marant-2

Hi,

  I'd like to use UNIX socket with Erlang but I did not
  find any module (both within the release and in contribs)
  supporting this.

  Can someone enlighten me? Has someone already implemented this?

  Thanks in advance.

--
J?r?me Marant <jerome.marant>
              <jerome>


Reply | Threaded
Open this post in threaded view
|

Using UNIX sockets with Erlang

Scott Lystig Fritchie-3
>>>>> "jm" == =?iso-8859-1?q?J=E9r=F4me?= Marant <jerome.marant> writes:

jm> I'd like to use UNIX socket with Erlang but I did not find any
jm> module (both within the release and in contribs) supporting this.

I haven't picked apart the R8 pre-release to see if UNIX domain
sockets were supported.  They are not in R7 and previous releases.  If
I recall correctly, they aren't supported because they aren't portable
to all platforms the Erlang VM runs on.  Someone more official could
probably give an official explanation.

When I was at Sendmail I wrote a UNIX domain socket driver.  It works
(for the RPC application we were working on at that time), but it
doesn't implement a lot of things that the TCP driver does (e.g. all
the {packet, PacketType} encoding types).  It's based on the TCP
driver code, so eventually we need to bundle it up into a useful
distribution and recontribute it back to the community as the license
demands.

If you're really, *really* itching to use it, I can try putting the
source together into something sortof-useful.  Let me know.

Here's a not-so-casual observation: the current implementation of the
Sendmail UNIX domain socket driver sends messages such as:

    {unixdom, Socket, Data}, {unixdom_closed, Socket},
    {unixdom_error, Socket, Reason}

... mimicing:

    {tcp, Socket, Data}, {tcp_closed, Socket}, {tcp_error, Socket, Reason}

However, it was a real pain to take code already written for TCP use
and use UNIX domain sockets instead: all the message pattern matching
had to be edited.  In contrast, the underlying API for stream-type
sockets is the same regardless of the family used.  Ditto for
datagram-type sockets.

-Scott


Reply | Threaded
Open this post in threaded view
|

Using UNIX sockets with Erlang

Jérôme Marant
Scott Lystig Fritchie <fritchie> writes:

> I haven't picked apart the R8 pre-release to see if UNIX domain
> sockets were supported.  They are not in R7 and previous releases.  If
> I recall correctly, they aren't supported because they aren't portable
> to all platforms the Erlang VM runs on.  Someone more official could
> probably give an official explanation.

  Of course, UNIX sockets don't work on other platforms than UNIX
  systems. However, you can always make the API behave differently
  with respect to the system it runs on, for instance returning some
  special error codes telling that there is no implementation for the
  function on that on that system.

>
> When I was at Sendmail I wrote a UNIX domain socket driver.  It works
> (for the RPC application we were working on at that time), but it
> doesn't implement a lot of things that the TCP driver does (e.g. all
> the {packet, PacketType} encoding types).  It's based on the TCP
> driver code, so eventually we need to bundle it up into a useful
> distribution and recontribute it back to the community as the license
> demands.

  Well, it seems that there is such a driver in the examples. However,
  I'd like to see it either as a contrib or as part of the Erlang
  release: there is no doubt that it more usefull than you can
  imagine.

>
> If you're really, *really* itching to use it, I can try putting the
> source together into something sortof-useful.  Let me know.

  I *really* want to use it. I'm currently coding a lightweight
  PostgreSQL client library in Erlang and I must be able to support
  both UNIX (for local connexions) and INET sockets.

  So yes, please release it ;-)

...
 
> However, it was a real pain to take code already written for TCP use
> and use UNIX domain sockets instead: all the message pattern matching
> had to be edited.  In contrast, the underlying API for stream-type
> sockets is the same regardless of the family used.  Ditto for
> datagram-type sockets.

  I can help, of course ;-)

  Cheers,

--
J?r?me Marant <jerome>
              <jerome.marant>


Reply | Threaded
Open this post in threaded view
|

Using UNIX sockets with Erlang

Scott Lystig Fritchie-3
>>>>> "jm" == =?iso-8859-1?q?J=E9r=F4me?= Marant <jmarant> writes:

jm> Of course, UNIX sockets don't work on other platforms than UNIX
jm> systems. However, you can always make the API behave differently
jm> with respect to the system it runs on, for instance returning some
jm> special error codes telling that there is no implementation for
jm> the function on that on that system.

Ja, I agree.  That argument hasn't had much traction so far, but
perhaps with more public demonstrations may help.  :-)

jm> Well, it seems that there is such a driver in the
jm> examples. However, I'd like to see it either as a contrib or as
jm> part of the Erlang release: there is no doubt that it more usefull
jm> than you can imagine.

Our RPC application saw about a 10% throughput improvement (bulk data
transfer) using UNIX domain sockets rather than TCP on the loopback
interface ... and no other code changes, other than changes to pattern
matching to accomodate the driver.  That was under FreeBSD.  If I did
any of those tests under Linux or Solaris, I don't recall their
results.

>>  If you're really, *really* itching to use it, I can try putting
>> the source together into something sortof-useful.  Let me know.

jm> So yes, please release it ;-)

The code is nasty ugly.  I started by taking the inet driver and
stripping out what wasn't needed by stream-type sockets, which made a
bit of a mess.  Not understanding all the details in the
descriptor-process-less driver design introduced in the R7 inet driver
just made things uglier.

I'll see what I can do in my spare time this week.  Like I said,
licensing compels us to release it.  It's public as-is already, if you
know where to look, but that isn't helpful right now.

-Scott


Reply | Threaded
Open this post in threaded view
|

Using UNIX sockets with Erlang

Scott Lystig Fritchie-3
>>>>> "slf" == Scott Lystig Fritchie <fritchie> writes:

slf> I'll see what I can do in my spare time this week.  Like I said,
slf> licensing compels us to release it.  It's public as-is already,
slf> if you know where to look, but that isn't helpful right now.

See http://www.snookles.com/erlang/ for a cleaned up and better-
documented-than-it-used-to-be source distribution for the Sendmail
UNIX-domain driver, unixdom-0.1.tar.gz.

I'll make a submission to the user contributions moderator, too.

-Scott


Reply | Threaded
Open this post in threaded view
|

Using UNIX sockets with Erlang (OT)

Rikard Elofsson
In reply to this post by Scott Lystig Fritchie-3
Scott Lystig Fritchie wrote:
>
> >>>>> "jm" == =?iso-8859-1?q?J=E9r=F4me?= Marant <jerome.marant> writes:
>
> jm> I'd like to use UNIX socket with Erlang but I did not find any
> jm> module (both within the release and in contribs) supporting this.

Hi all, I don't know much about Erlang and i work with Java, but i hope
its ok if i ask a question anyway. Is there some kind of possibility
to get to the packet level in Erlang, that is, not use sockets? I would
like to implement firewall-like behaviour via ipfilter, BPF or something
like that. Is there any possibility of getting that close to the machine
in Erlang or is one bound to use TCP sockets? And yes i havent been monitoring
this thread so if its been duscussed plz let me know.

One more:
I tried to write a small HTTP server in Erlang, stole code from an example,
dont know from where, sorry, and performance is no good, at least on NT.
(attached) If i do 50 requests from 20 clients, (1000) about 20 of them
fail with "connection refused". Am i doing something wrong or is this
expected behaviour?

Again, dont hurt me:), i just want to try Erlang out...

Regards
//Rikard
-------------- next part --------------
A non-text attachment was scrubbed...
Name: httptest.erl
Type: application/x-unknown-content-type-erlangsourcefile
Size: 1264 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20010919/d51e2503/attachment.bin>

Reply | Threaded
Open this post in threaded view
|

Using UNIX sockets with Erlang (OT)

tobbe

> I would
> like to implement firewall-like behaviour via ipfilter, BPF or something
> like that. Is there any possibility of getting that close to the machine
> in Erlang or is one bound to use TCP sockets?

Well, I've written some simple drivers in C, using BPF
on FreeBSD and 'raw-packet' sockets on Linux, which
delivers Ethernet frames upto Erlang.
You'll find them here (among lots of other code):

 http://www.bluetail.com/~tobbe/etcp/

Cheers /Tobbe



Reply | Threaded
Open this post in threaded view
|

Using UNIX sockets with Erlang (OT)

Claes Wikström
In reply to this post by Rikard Elofsson

> (attached) If i do 50 requests from 20 clients, (1000) about 20 of them
> fail with "connection refused". Am i doing something wrong or is this
> expected behaviour?
>

Ok, "connection refused" is what you typically get when the listen
backlog queue is full on the server machine. You get this because
there is time-gap in your code where nobody is accept() 'ing.

You need to make sure that there is always some code that sits
in accept(). One way is to pre spawn the worker process, do the
accept, send the socket to the pre spawned process, and then
accept() again.

There is also a {backlog, Num} option that can be passed to
listen().

Another observation is that the regex and string handling in
your code will make it slow. However, that's not your fault, it's
erlang strings that suck. Maybe use binaries.


/klacke


--
Claes Wikstrom                        -- Caps lock is nowhere and
Alteon WebSystems                     -- everything is under control          
http://www.bluetail.com/~klacke       --



Reply | Threaded
Open this post in threaded view
|

Using UNIX sockets with Erlang

Jérôme Marant-2
In reply to this post by Scott Lystig Fritchie-3
Scott Lystig Fritchie <fritchie> writes:

> >>>>> "slf" == Scott Lystig Fritchie <fritchie> writes:
>
> slf> I'll see what I can do in my spare time this week.  Like I said,
> slf> licensing compels us to release it.  It's public as-is already,
> slf> if you know where to look, but that isn't helpful right now.
>
> See http://www.snookles.com/erlang/ for a cleaned up and better-
> documented-than-it-used-to-be source distribution for the Sendmail
> UNIX-domain driver, unixdom-0.1.tar.gz.
>
> I'll make a submission to the user contributions moderator, too.

  Yes, please.

  Thanks a lot.

--
J?r?me Marant <jerome.marant>
              <jerome>


Reply | Threaded
Open this post in threaded view
|

Multple Application Management

Martin Carlson-2
In reply to this post by Scott Lystig Fritchie-3
Hello,
    I am wondering if anyone can help point me in the correct direction for
the deployment of multimple applications on one node.
Currently I manage applications on a per application basis i.e they are
started individually. I start the runtime system pointing it to the script
and boot files that I genereated for that particular application using
systools.  I want to run two applications on the same box so pointing the
system to the script and boot files generated for specific apps is not
feasable. I would like to have all the startup info in one central location
so that all the apps I woudl like started on a box would come up when I start
the the run time system. I have messed with the start.script file but this
requires me to edit it manually which I understand from the docs is not the
preferred way to go about things. Could someone point me tword the proper way
to manage somthing like this? What method lies in accordence with the way the
run time system was designed?
                Thanks,
                Martin Logan



Reply | Threaded
Open this post in threaded view
|

Multple Application Management

Ulf Wiger-4
On Mon, 3 Dec 2001, Martin J. Logan wrote:

>Hello,

>I am wondering if anyone can help point me in the correct
>direction for the deployment of multimple applications on one
>node. Currently I manage applications on a per application
>basis i.e they are started individually. I start the runtime
>system pointing it to the script and boot files that I
>genereated for that particular application using systools.

Hmm, there isn't really a short answer for this one, but let's
give it a go.

- Let's say you want to build a system called 'mysystem', which
  is made up of the applications 'a' and 'b'. You would then first
  write a .rel file:

mysystem.rel:

{release,{"mysystem","1.0"},
         {erts,"5.0.2.11"},
         [{kernel,"2.6.3.6"},
          {stdlib,"1.9.4.2"},
          {sasl,"1.9.2"},
          {mnesia,"3.10.3"},
          {a,"0.9"},
          {b,"0.7"}]}.

- You pick a directory under which to install the system, let's
  say /usr/local/lib/mysystem/

- You create a directory for the release files:

/usr/local/lib/mysystem/releases/1.0

(where 1.0 is the system version listed in mysystem.rel)
Copy mysystem.rel into the above directory.

- I will assume that your applications are in the following path:

/usr/local/lib/mysystem/lib/a/ebin
/usr/local/lib/mysystem/lib/b/ebin

- Go to the releases/1.0 directory, start an erlang shell, and
  write:

   systools:make_script(
         "mysystem",
         [{path, ["/usr/local/lib/mysystem/lib/*/ebin"]}]).


This will (if you're lucky) generate a start.script and a
start.boot file.


- You can then start your system using the command:

erl -boot /usr/local/lib/mysystem/releases/1.0/start


There is normally more to it than that, but if you do it in this
way, you can then build on it to add more sophisticated release
handling.

If your applications need to start in a specific order, e.g. 'b'
cannot start until 'a' is started, then you would put the
following attribute in b's .app file:

  {applications, [a]}

Then, systools will make sure that the application start
instructions arrive in the right order, and the application
controller will honor the dependency.

/Uffe

>I want to run two applications on the same box so pointing the
>system to the script and boot files generated for specific apps is not
>feasable. I would like to have all the startup info in one central location
>so that all the apps I woudl like started on a box would come up when I start
>the the run time system. I have messed with the start.script file but this
>requires me to edit it manually which I understand from the docs is not the
>preferred way to go about things. Could someone point me tword the proper way
>to manage somthing like this? What method lies in accordence with the way the
>run time system was designed?
>                Thanks,
>                Martin Logan
>
>

--
Ulf Wiger, Senior Specialist,
   / / /   Architecture & Design of Carrier-Class Software
  / / /    Strategic Product & System Management
 / / /     Ericsson Telecom AB, ATM Multiservice Networks



Reply | Threaded
Open this post in threaded view
|

Multple Application Management

Vance Shipley-2
Martin,

Your question strikes a familiar chord with me.  My view of
the Erlang/OTP environment is that it should support multiple
applications in the same way that a Unix server does.  I
should be able to hand you a release package to install on
your node with applications A & B running and after installing
you'd now have A, B & C running.

The OTP provides some wonderful tools for building "applications",
packaging them into "releases" and installing them on running
systems handling necessary dependencies and code upgrades.  It
doesn't however work sjust described.

If you have built your applications using the design principles
of the application module you are able to load, start and stop
individual applications easily as in application:start(foo).
You can even move distributed applications from node to node.
Using this you can have a dynamic set of applications coming
and going as you wish.

The problem is with the release_handler.  The view taken is a
practical one which is directed at deploying embedded systems
as products in the field.  The design assumes that you have a
complete view of what is running on that system.  You create a
foo.rel file which describes all the applications required and
the release package created includes all the files for all these
applications including kernel and stdlib.

When I built my first release I ran straight into this difference
of mind set when I tried to install it.  I found that there was
no way to install it!  You can unpack it with
release_handler:unpack_release(foo) but if you try to use
release_handler:install_release(foo) you will find that you need
a release upgrade script (relup).  There doesn't appear to be a
valid syntax for the relup file which will allow "upgrading" from
a non-existent release.

At this point the big picture came into view as I realized that
there could only be one permanent release on the system.  Once
you have made a release permanent with
release_handler:make_permanent(foo) that defines the boot file
which will be run at start up in an embedded system.  That boot
script is included in the release package so it obviously doesn't
know anything about your existing applications.

What I would like to do is to rewrite the release_handler module
to handle merging releases into one boot script.  When a new
release package is provided it could look at what other releases
are incorporated into the system and merge them together into one
boot script.  

Uffe described a manual way of doing this which is really the
definitive answer to your question.  It is much better to use the
systools to create a boot script from the release file than to try
and edit the boot script directly.  In this way you can edit the
foo.rel file and rerun systools:make_script(foo) each time the
set of applications you want running permanently changes.

        -Vance


> On Mon, 3 Dec 2001, Martin J. Logan wrote:
>
> >Hello,
>
> >I am wondering if anyone can help point me in the correct
> >direction for the deployment of multiple applications on one
> >node. Currently I manage applications on a per application
> >basis i.e they are started individually. I start the runtime
> >system pointing it to the script and boot files that I
> >generated for that particular application using systools.
>


Reply | Threaded
Open this post in threaded view
|

Multple Application Management

Ulf Wiger-4
On Tue, 4 Dec 2001, Vance Shipley wrote:

>Your question strikes a familiar chord with me.  My view of the
>Erlang/OTP environment is that it should support multiple
>applications in the same way that a Unix server does.  I should
>be able to hand you a release package to install on your node
>with applications A & B running and after installing you'd now
>have A, B & C running.
>
>The OTP provides some wonderful tools for building
>"applications", packaging them into "releases" and installing
>them on running systems handling necessary dependencies and
>code upgrades.  It doesn't however work sjust described.


The AXD 301 has functionality similar to what you describe. We
have the possibility to add applications to an already running
system, and if a new version of an already running application is
made available, the software management component will figure out
how to upgrade the system with it.

This is done with the help of a layer on top of the release
handler, and some design rules. One of the important things is
that there must be a framework for initializing mnesia tables,
and registering system resources (such as web menus and pages,
alarm types, and distribution groups). It should also be
possible, of course, to unregister the same, if an application is
to be removed.

This stuff could hypothetically be made available as Open Source,
but we don't have the resources to do that at AXD 301.

/Uffe
--
Ulf Wiger, Senior Specialist,
   / / /   Architecture & Design of Carrier-Class Software
  / / /    Strategic Product & System Management
 / / /     Ericsson Telecom AB, ATM Multiservice Networks


Reply | Threaded
Open this post in threaded view
|

Multple Application Management

Hal Snyder-2
Ulf Wiger <etxuwig> writes:

> The AXD 301 has functionality similar to what you describe. We have
> the possibility to add applications to an already running system,
> and if a new version of an already running application is made
> available, the software management component will figure out how to
> upgrade the system with it.

> This is done with the help of a layer on top of the release
> handler, and some design rules. One of the important things is
> that there must be a framework for initializing mnesia tables,
> and registering system resources (such as web menus and pages,
> alarm types, and distribution groups). It should also be
> possible, of course, to unregister the same, if an application is
> to be removed.
>
> This stuff could hypothetically be made available as Open Source,
> but we don't have the resources to do that at AXD 301.

I work with Martin at Vail and have been following this thread with
great interest. Like Vance, I'd like to think of an Erlang cluster as
a collection of servers onto which new apps are occasionally deployed
without restarting the nodes. I don't think this notion fits very well
with boot files.

I wonder about the feasibility of several nodes with very generic
startup config, plus a couple management nodes from which new code is
injected into the platform.

We use Erlang for several similar-looking apps - servers that do
various queries and resource allocation for our computer telephony
platform, a middle layer between speech servers and the resources they
need. It would be very interesting to learn more about the "extra
layer" mentioned above. Meanwhile, I wonder we shouldn't just
structure what is running on our servers as a single app, and add new
functions to it as needed. Does that make sense? I have a bad cold, so
it might not. :)