directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Karasulu <>
Subject [Mitosis] IM Session with Trustin
Date Tue, 07 Nov 2006 03:55:23 GMT
Hi all,

I'd like to report on some questions, their answers and some conclusions 
reached while Trustin and I were talking on IM about Mitosis:

======================= Start =========================

1). When adding an entry that was already marked entryDeleted true, why 
does mitosis perform a modify operation on the entry instead?

Answer: I don't remember maybe I did it this way because of a lack of 

2). In the OperationFactory.newAdd(CSN,LdapDN,Attributes) method the 
first thing you do is call checkBeforeAdd(LdapDN) whose short body is 
printed out below:

     private void checkBeforeAdd( LdapDN newEntryName ) throws 
         if ( nexus.hasEntry( newEntryName ) )
             throw new NameAlreadyBoundException( 
newEntryName.toString() + " already exists." );

On add operations where the entry is marked entryDeleted=true, this 
method always throws an exception and shorts the progress of the add() 
operation.  I have modified it to check if the entry is marked as 
deleted first before throwing an exception like so:

     private void checkBeforeAdd( LdapDN newEntryName ) throws 
         if ( nexus.hasEntry( newEntryName ) )
             Attributes entry = nexus.lookup( newEntryName );
             Attribute deleted = entry.get( Constants.ENTRY_DELETED );
             Object value = deleted == null ? null : deleted.get();

              * Check first if the entry has been marked as deleted before
              * throwing an exception and delete the entry if so and return
              * without throwing an exception.
             if ( value != null && "true".equalsIgnoreCase( 
value.toString() ) )

             throw new NameAlreadyBoundException( 
newEntryName.toString() + " already exists." );

Now is this the right thing to do?

Answer: Yes this is good.

3).  After making this change I still have some problems.  Let me 
describe the sequence of events in terms of 2 replicas A and B and an 
add operation:

   (i) add entry (1) to replica A

Everything is fine up to now.  Replication of the add propagates just 
fine.  I can see the entry in both replica A and B.

   (ii) delete entry (1) from replica A

Everything is fine up to now.  Replication of the del propagates just 
fine.  I can not see the entry in either replica A and B.  Pulling up 
the diagnostic gui I can see that the entry is in the partition but 
marked entryDeleted = true.

   (iii) add entry (1) back to replica A with same DN and same contents

Here I get a *FAILURE*.  The error response I get from the server is:

06:06:49 PM: Failed to add new entry ou=neworganizationalUnit, 
dc=example,dc=com Root error: [LDAP: error code 80 - failed to add entry
ou=neworganizationalUnit,dc=example,dc=com: Unexpected exception.]

In fact I get this error if I try to add to either replica A or B. At 
this point I started a debug session to determine exactly what is going 
on which prevents this 2nd add operation from working.

3a). I noticed that for add you build a CompositeOperation but really 
you're only putting into it a single AddEntryOperation.  Did you intend 
to do this or is it a simple bug?

Answer: Yeah you are right we don't need to wrap it.

3b). To the entry to be added you remove any entryDeleted and entryUUID 
attributes and add a entryDelete (false), entryUUID and an entryCSN 
attribute.  Then execute() is called eventually for the 
AddEntryOperation.  Here you're checking if the entry is updateable by 
calling EntryUtil.isEntryUpdatable.   Here's the code for it:

Basically you lookup the entry with a call to the nexus.  Then you 
return true if the entry does not exist.  Is this valid?  Meaning if the 
entry does not exist in the store how can it be updatable?

You also check if there is no CSN attribute.  If there is no attribute 
then you return true that the entry is updatable.  What does this mean?

It would help if you clarify the meaning of these methods in EntryUtils 
with a bit more doco.  Also it would be nice if you elaborate more on 
how mitosis does not delete entries, and why it does this as well as 
when and how it cleans up later.  This is all critical stuff for the 
architecture that was omitted.


(20:52:07) trustin: first, if there's no entryCSN attribute, it means that
(20:52:24) trustin: an entry is added before          Mitosis is in action.
(20:52:55) akarasulu: ahh ok
(20:53:02) trustin: so it should be updatable and needs to get the CSN 
assigned by modification
(20:53:09) akarasulu: ok
(20:53:23) trustin: and then it compares the CSN
(20:53:37) akarasulu: why do you return true if entry == null ?
(20:54:28) trustin: Semantics of update includes both add and modify.. 
so it's updatable if there's no such entry.
(20:54:42) akarasulu: ahhh ok so add is considered an update
(20:54:58) trustin: yeah update is all operations that affects the DIT.

3c). The code goes past these checks for this scenario since the entry 
does exist and is marked entryDeleted: true and it does have a CSN 
attribute.  Finally you compare whether this old CSN is older than the 
new CSN.  If so then you return true.

What is the meaning of this?  Is it just an undefined situation where 
you should not be changing an entry with CSN that is older than the CSN 
of the original entry?  Why then return true or false for 
isEntryUpdatable?  Should you not just throw an exception if this
is just an undefined situtation?

Answer: We need to decide between two CSN's, the existing one or the new 
operation at hand.

3d). Next you create glue entries.  This is not very clear to me.  It 
was not in your architecture document.  I think it is very important to 
define exactly what this is for to understand mitosis.

Inside EntryUtils.createGlueEntries() you are using getSuffix() to walk 
a DN.   How do you intend to walk the DN?  From the top down like so for 


For each one you are trying to create a glue entry I think.  There was 
yet no need for a glue entry but we have to understand what it is and 
make sure they don't violate schema or we'll bomb out.  Can you 
elaborate a little on glue entries?

Answer: will put it into another iteration of the mitosis architecture doco.

3e). In an effort to modify the entry you are removing all attributes 
that the two old and new entries do not have in common.  However you are 
removing these from the cloned version of the old entry.  Then you never 
use this old entry that has attributes removed from it.

Is this another bug?

Answer: Yes

4) If I restart a server after shuting it down I get the following error 
and the server dies:

     Caused by: Address already in use

We found a way to stop this from happening with the LDAP port used by 
the server.  Can
we make the mitosis replication service port also behave similarly so 
this does not

Answer: config.setReuseAddress( true );

5). Looks like you have not finished implementing the move operation as 
is indicated
here in OperationFactory line 188 in newMove():

         if ( !deleteOldRn )
             throw new OperationNotSupportedException( "deleteOldRn must 
be true." );

Is it that you did not implement this or that it was not possible 
because of some issue?

6). Can you please add some internal documentation to the mitosis code?

Answer: Yep

7). Can you update the archtecture documentation to include information 
about glue entries, not deleting and cleaning up stuff?

Answer: Yep

8). Could you also elaborate more on the log and how it is used?

Answer: Yep

9). Can we detect when we are out of sync and email administrators?

(22:46:27) akarasulu: yes right ?
(22:46:33) trustin: yes.



(1) We need to log when we have dropped operations.
(2) We need to email administrators when we have dropped ops and/or when 
we are out
of sync.

Decided it is best to recursively delete entries marked as deleted when 
  re-adding the
entry from scratch.


View raw message