[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: PATCH: back-sock



It certainly sounds like an improvement over back-shell, and there may be some value in keeping the perl interpreter outside the slapd process. But you should read http://www.openldap.org/devel/contributing.html. New code should be provided as a patch against HEAD. 2.2 was feature-frozen long ago and is pretty much at end-of-life now, so a patch against 2.2.26 isn't going to do anybody much good.

Brian Candler wrote:
Hello,

Back in May I posted a "back-sock" backend to the openldap-software list:
http://www.openldap.org/lists/openldap-software/200505/msg00343.html

I didn't get any response, but in retrospect, perhaps openldap-devel would
have been more appropriate.

Anyway, it's attached again. Is anyone interested in doing anything with
this?

Regards,

Brian Candler.


------------------------------------------------------------------------

Subject:
[PATCH] back-sock
From:
Brian Candler <B.Candler@pobox.com>
Date:
Thu, 26 May 2005 15:34:18 +0100
To:
openldap-software@openldap.org

To:
openldap-software@openldap.org


I have put together a new backend, 'back-sock', based heavily on back-shell. I invite people to look, test, and comment; if feedback is positive I'll submit it as a patch via ITS. The patch to openldap-2.2.26 is at http://psg.com/~brian/software/openldap-backsock.diff.gz


The intention behind this backend is to give something with the flexibility of back-perl and the simplicity of back-shell, but with high enough performance for real world applications rather than just prototypes.

back-perl is throttled by being single-threaded: each entry into the perl interpreter is protected by a mutex call, so that only one request at a time can be handled. back-shell is worse as it forks a new child for each request, as well as not supporting threading.

back-sock attempts to address this problem by passing requests down a unix-domain socket. You can then build a pool of worker processes (e.g. with Net::Server in perl) each of which handles one request at a time. A trivial sample is included as servers/slapd/back-sock/searchexample.pl

The protocol sent down the socket is the same as back-shell, with the addition of a blank line to indicate the end of the request. The worker process reads the request, sends its response in back-shell format, then closes the socket.

These worker processes should be persistent and can each hold open a persistent database handle, so you should get decent concurrency on applications which query a SQL database for example.

Sample performance results on a 2.8GHz Pentium4 running FreeBSD 5.4:
- searchexample.pl as the server backend
- 10 client processes in perl using Net::LDAP each to send 100 requests
- total real time to complete those 1000 requests:

7 seconds       -- back-sock, fresh TCP connection opened for each query
5 seconds       -- back-null, fresh TCP connection opened for each query
4 seconds       -- back-sock, each client holds open a single connection
2 seconds       -- back-null, each client holds open a single connection

This is with the clients and server all running on the same machine.

Unfortunately, I was once able to make openldap crash:

Assertion failed: (!FD_ISSET( s, &slap_daemon.sd_actives)), function slapd_daemon_task, file daemon.c, line 1604.
Abort trap (core dumped)


This makes me suspect I'm doing something in a non-thread-safe way. Any advice here would be much appreciated.

Missing bits: I haven't written a manpage. Also, I re-used LDAP_DEBUG_SHELL rather than defining a new debug flag for this module. See comments marked "FIXME" in the patch for other areas I think could be improved.

Regards,

Brian Candler.

--------
P.S. here's the test client program used above

#!/usr/bin/perl -w

use Net::LDAP;

my $uri = "ldap://localhost";;
my $concurrency = 10;
my $numhits = 100;   # per process

sub do_kid();

for (my $i = 0; $i < $concurrency; $i++) {
  my $pid = fork();
  if ($pid == 0) {
    do_kid();
    exit 0;
  }
}

for (my $i = 0; $i < $concurrency; $i++) {
  $pid = wait();
  print STDERR "Child pid $pid terminated\n";
}
exit 0;

sub do_kid() {
for (my $j =0; $j < $numhits; $j++) {
my $ldap = Net::LDAP->new($uri) or die "$@";
$mesg = $ldap->search(
base=>'dc=example,dc=com',
filter=>'(objectclass=*)'
);
$mesg->code && die $mesg->error;
#foreach $entry ($mesg->entries) { print STDERR $entry->dn,"\n"; }
$ldap->unbind;
}
}


--
 -- Howard Chu
 Chief Architect, Symas Corp.  http://www.symas.com
 Director, Highland Sun        http://highlandsun.com/hyc
 OpenLDAP Core Team            http://www.openldap.org/project/