Let me try to explain why you are seeing this.

Each method called on $ldap does not return until it sees the final
response packet for the ldap query. However the callback method is
called for each packet. The server has already sent, or queued to
send, the results from the search before you send the modif. This is
why you see all the aaaa's followed by the bbbb's

Your second approach avoids this by have two pipes to the server.
Your call to ->modify can now return without having to process all the
results from the search first.

The reason it is slower is that in your first case, when you call
->modify Net::LDAP will immediately process the next search result. In
the second case you have to wait for the modify response.

One possible way to solve this is to use the async mode of Net::LDAP
and use a callback on the modify command.

After calling ->search call $ldap->sync. This will not return until
all requests have been completed. Initially this is just the search,
but as your callback calls modify it will not return untill all of
those are completed too.

But the calls to ->modify will return immediately. Just do not call
->code on the response as that implies a sync point and you will be in
the same position.  You will need to pass a callback to modify to
check the response codes

Graham.

On Apr 12, 2005, at 2:55 AM, Giacomo Cerrai wrote:

Well, I did some further investigation and found out that indeed
the call to ldapmodify triggers the callback, set in the ldapsearch call,
thus resulting in recursion.
I put a couple of debug prints in the callback code like this:


        printf "aaaaaaaaa\n";
        my $modify = $ldap->modify(...);
        printf "bbbbbbbbb\n";

And this is the output:
...
aaaaaaaaa
aaaaaaaaa
aaaaaaaaa
aaaaaaaaa
Search complete
bbbbbbbbb
bbbbbbbbb
bbbbbbbbb
bbbbbbbbb
...

I've also found a decent solution/workaround.
I can use two different ldap connections one for the search
and the other one for the modify:

  my $ldap  = Net::LDAP->new($ldap_server) or die "$@";
  my $ldapm = Net::LDAP->new($ldap_server) or die "$@";
  ...
  $mesg = $ldap->search(..);
  ...
  my $modify = $ldapm->modify(
  ...

This works, the only drawback is that the modify rate is now
less than half the one with a single connection.
This is actually a big slowdown.
I would still like to know if there's a better way to do it.

thanks
g.


Giacomo Cerrai wrote:

The code is like:
...
$mesg = $ldap->search( base   => $base_dn,
                       scope  => 'ONE',
                       filter => "username=*",
                       attrs  => [EMAIL PROTECTED],
                       callback => \&process_entry
                     );

...
sub process_entry {
    my $mesg = shift;
    my $obj = shift;

    if (!$obj) {
       print "Search complete\n";
    }
    elsif ($obj->isa('Net::LDAP::Reference')) {
        ...
    }
    else {
        # don't use $obj, pop_entry it to free memory
        my $entry = $mesg->pop_entry;
        unless ($entry) {
            warn "Cannot pop entry!\n";
            return;
        }
        ...
        my $modify = $ldap->modify(
        ...
    }
}






Reply via email to