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( ... } }
