LDAPReplicationDomain.applyConfigurationChange() swaps the new configuration in as its first act,
long before it knows whether applying it worked
(opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/LDAPReplicationDomain.java:4555-4584):
public ConfigChangeResult applyConfigurationChange(ReplicationDomainCfg configuration)
{
this.config = configuration;
synchronized (serviceStateLock)
{
changeConfig(configuration);
readAssuredConfig(configuration, true);
readFractionalConfig(configuration, true);
}
solveConflictFlag = isSolveConflict(configuration);
final ConfigChangeResult ccr = new ConfigChangeResult();
try
{
storeECLConfiguration(configuration);
}
catch(Exception e)
{
ccr.setResultCode(ResultCode.OTHER);
}
return ccr;
}
When storeECLConfiguration() throws, the administrator is told the modification failed
(ResultCode.OTHER), but the domain is already running on the configuration it just rejected: the
field, the broker configuration, the assured configuration and the fractional configuration were all
changed above.
Every property this domain reads from config is then live although the change was reported as
unsuccessful:
Nothing here is new - the ordering predates every one of those readers - but the failure is silent in
both directions: the operator sees an error and has to guess what part of their change took, and a
subsequent dsconfig read shows the entry as modified, because the entry itself was written before
the listener ran.
What it would look like
Either the assignment and the three read*Config() calls move after the step which can fail, or the
domain keeps the previous configuration and restores it when the result code is not SUCCESS. Both
need care: changeConfig() and readAssuredConfig() stop and start the session under
serviceStateLock, so an "undo" is not a plain field assignment, and storeECLConfiguration() reads
config through getBaseDN()/config.dn(). The cheap half is to decide - and to write down - which
of the two the domain owes its administrator.
Raised from the review of the #901 branch.
LDAPReplicationDomain.applyConfigurationChange()swaps the new configuration in as its first act,long before it knows whether applying it worked
(
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/LDAPReplicationDomain.java:4555-4584):When
storeECLConfiguration()throws, the administrator is told the modification failed(
ResultCode.OTHER), but the domain is already running on the configuration it just rejected: thefield, the broker configuration, the assured configuration and the fractional configuration were all
changed above.
Every property this domain reads from
configis then live although the change was reported asunsuccessful:
config.getIsolationPolicy()(:1836)config.isLogChangenumber()(:2122)config.getConflictsHistoricalPurgeDelay()(:5686)config.getReplayGiveUpDelay(), once Make the replay retry budget of a replication domain configurable instead of a constant with a test-only setter #901 landsNothing here is new - the ordering predates every one of those readers - but the failure is silent in
both directions: the operator sees an error and has to guess what part of their change took, and a
subsequent
dsconfigread shows the entry as modified, because the entry itself was written beforethe listener ran.
What it would look like
Either the assignment and the three
read*Config()calls move after the step which can fail, or thedomain keeps the previous configuration and restores it when the result code is not
SUCCESS. Bothneed care:
changeConfig()andreadAssuredConfig()stop and start the session underserviceStateLock, so an "undo" is not a plain field assignment, andstoreECLConfiguration()readsconfigthroughgetBaseDN()/config.dn(). The cheap half is to decide - and to write down - whichof the two the domain owes its administrator.
Raised from the review of the #901 branch.