Fix for [Issue 798] break infinite loop when problems with naming resolution conflict. Reviewed by gbellato.
The fix is to replay the operation a maximum of 10 times. There is a unit test for this issue that uses the short-circuit plugin to force the infinite replay loop.
| | |
| | | CATEGORY_MASK_SYNC | SEVERITY_MASK_SEVERE_ERROR | 34; |
| | | |
| | | /** |
| | | * Loop detected while replaying an operation. This message takes one |
| | | * string argument containing details of the operation that could not be |
| | | * replayed. |
| | | */ |
| | | public static final int MSGID_LOOP_REPLAYING_OPERATION = |
| | | CATEGORY_MASK_SYNC | SEVERITY_MASK_MILD_ERROR | 35; |
| | | |
| | | /** |
| | | * Register the messages from this class in the core server. |
| | | * |
| | | */ |
| | |
| | | MessageHandler.registerMessage( |
| | | MSGID_EXCEPTION_RECEIVING_SYNCHRONIZATION_MESSAGE, |
| | | "An Exception was caught while receiving synchronization message : %s"); |
| | | MessageHandler.registerMessage(MSGID_LOOP_REPLAYING_OPERATION, |
| | | "A loop was detected while replaying operation: %s"); |
| | | } |
| | | } |
| | |
| | | Operation op = null; |
| | | boolean done = false; |
| | | ChangeNumber changeNumber = null; |
| | | int retryCount = 10; |
| | | |
| | | try |
| | | { |
| | | while (!done) |
| | | while (!done && retryCount-- > 0) |
| | | { |
| | | op = msg.createOperation(conn); |
| | | |
| | |
| | | done = true; |
| | | } |
| | | } |
| | | |
| | | if (!done) |
| | | { |
| | | // Continue with the next change but the servers could now become |
| | | // inconsistent. |
| | | // TODO : REPAIR : Should let the repair tool know about this |
| | | int msgID = MSGID_LOOP_REPLAYING_OPERATION; |
| | | String message = getMessage(msgID, op.toString()); |
| | | logError(ErrorLogCategory.SYNCHRONIZATION, |
| | | ErrorLogSeverity.SEVERE_ERROR, message, msgID); |
| | | updateError(changeNumber); |
| | | } |
| | | } |
| | | catch (ASN1Exception e) |
| | | { |
| | |
| | | * [Issue 798] break infinite loop when problems with naming resolution |
| | | * conflict. |
| | | */ |
| | | @Test(enabled=false) |
| | | @Test(enabled=true) |
| | | public void infiniteReplayLoop() throws Exception |
| | | { |
| | | final DN baseDn = DN.decode("ou=People,dc=example,dc=com"); |