Hello,
I was investigating the alternative/impacts of a new plugin and I would like to share some thoughts and check I did not miss something important.
Here is the description of the problem we want to address. In MMR topology, we have an entry containing a single valued attribute. It is an integer syntax attribute. Our need is that the attribute can only be increased. So if its initial value is 5, an update MOD/REPL '6' is valid and applied, while MOD/REPL '3' is invalid and rejected/ignored. Also being in MMR, the attribute can be updated on several instances.
The current approach is to create a BE_PREOP or BE_TXN_PREOP plugin. This allow to retrieve the current value from the pblock (SLAPI_ENTRY_PRE_OP) and guaranties the value is exact as only one operation is processed at a time.
The plugin registers a mod operation callback. It controls the new_value vs current_value to check that new_value >current_value. The plugin will update the mods. In particular translates a MOD/REPL into a MOD/DEL(current value) + MOD/ADD(new_value).
Regarding the change of the MODS (mod/repl -> mod/del + mod/add), the plugin should be a BE_PREOP. This is because MODS are applied after BE_PREOP plugins, then new MODS added by BE_TXN_PREOP plugins are applied. A BE_TXN_PREOP plugin may translate mod/repl -> mod/del+mod/add but it is too late, mod/repl has already been applied after BE_PREOP plugins were called.
Regarding replication, for non replicated updates, it should just reject (unwilling to perform) ops with new_value < current_value. For replicated update I see the two cases ([server / csn / attribute value] ): [A/csnA/valueA], [B/csnB/valueB] and the expected final value is ValueB+csnB
1. csnA < csnB and ValueA < ValueB. 1. When server A receives csnB/valueB, this is fine as ValueB>ValueA. But to know that ValueB will be selected the plugin needs to check that csnB>csnA. 1. When server B receives csnA/valueA it has 3 possibilities: 1. reject (unwilling to perform) the update. But then replication A->B will fail indefinitely 2. erase the update. For example the plugin could erase the mod from the set of mod. 3. let the operation continue because csnA < csnB, the kept value will be ValueB. Here again the plugin needs to check csnA vs csnB 2. csnA > csnB and ValueA < ValueB. 1. When server A receives csnB/valueB, this is fine as ValueB>ValueA. But to know that ValueB will be selected the plugin need to check that csnB>csnA. 2. When server B receives csnA/valueA it has 2 possibilities: 1. reject (unwilling to perform) the update. But then replication A->B will fail indefinitely 2. erase the update. For example the plugin could erase the mod from the set of mod.
So I think the plugin should not rely on the new_value present in the operation but rather computes the final_value (taking into account the CSN). If the final_value > current_value, it let the operation going on (even if the new_value in the operation < current_value). If the final_value < current_value it should remove the mod from the mods (2.2.2) and likely log a message.
Changing MOD/REPL into MOD/DEL+ MOD/ADD is a possibility but the attribute being single valued I think it is not mandatory.
Thanks thierry
On 09/24/2014 04:33 AM, thierry bordaz wrote:
Hello,
I was investigating the alternative/impacts of a new plugin and I would like to share some thoughts and check I did not miss something important. Here is the description of the problem we want to address. In MMR topology, we have an entry containing a single valued attribute. It is an integer syntax attribute. Our need is that the attribute can only be increased. So if its initial value is 5, an update MOD/REPL '6' is valid and applied, while MOD/REPL '3' is invalid and rejected/ignored. Also being in MMR, the attribute can be updated on several instances. The current approach is to create a BE_PREOP or BE_TXN_PREOP plugin. This allow to retrieve the current value from the pblock (SLAPI_ENTRY_PRE_OP) and guaranties the value is exact as only one operation is processed at a time. The plugin registers a mod operation callback. It controls the new_value vs current_value to check that new_value >current_value. The plugin will update the mods. In particular translates a MOD/REPL into a MOD/DEL(current value) + MOD/ADD(new_value). Regarding the change of the MODS (mod/repl -> mod/del + mod/add), the plugin should be a BE_PREOP. This is because MODS are applied after BE_PREOP plugins, then new MODS added by BE_TXN_PREOP plugins are applied. A BE_TXN_PREOP plugin may translate mod/repl -> mod/del+mod/add but it is too late, mod/repl has already been applied after BE_PREOP plugins were called. Regarding replication, for non replicated updates, it should just reject (unwilling to perform) ops with new_value < current_value. For replicated update I see the two cases ([server / csn / attribute value] ): [A/csnA/valueA], [B/csnB/valueB] and the expected final value is ValueB+csnB 1. csnA < csnB and ValueA < ValueB. 1. When server A receives csnB/valueB, this is fine as ValueB>ValueA. But to know that ValueB will be selected the plugin needs to check that csnB>csnA. 1. When server B receives csnA/valueA it has 3 possibilities: 1. reject (unwilling to perform) the update. But then replication A->B will fail indefinitely 2. erase the update. For example the plugin could erase the mod from the set of mod. 3. let the operation continue because csnA < csnB, the kept value will be ValueB. Here again the plugin needs to check csnA vs csnB 2. csnA > csnB and ValueA < ValueB. 1. When server A receives csnB/valueB, this is fine as ValueB>ValueA. But to know that ValueB will be selected the plugin need to check that csnB>csnA. 2. When server B receives csnA/valueA it has 2 possibilities: 1. reject (unwilling to perform) the update. But then replication A->B will fail indefinitely 2. erase the update. For example the plugin could erase the mod from the set of mod. So I think the plugin should not rely on the new_value present in the operation but rather computes the final_value (taking into account the CSN). If the final_value > current_value, it let the operation going on (even if the new_value in the operation < current_value). If the final_value < current_value it should remove the mod from the mods (2.2.2) and likely log a message.
What happens if ValueA == ValueB and csnA != csnB? Do we want to allow the same value to be issued by two different servers? Is this a case as with DNA and uidNumber, that we assign servers to have ranges?
Changing MOD/REPL into MOD/DEL+ MOD/ADD is a possibility but the attribute being single valued I think it is not mandatory. Thanks thierry
-- 389-devel mailing list 389-devel@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/389-devel
On 09/25/2014 04:32 AM, Rich Megginson wrote:
On 09/24/2014 04:33 AM, thierry bordaz wrote:
Hello,
I was investigating the alternative/impacts of a new plugin and I would like to share some thoughts and check I did not miss something important. Here is the description of the problem we want to address. In MMR topology, we have an entry containing a single valued attribute. It is an integer syntax attribute. Our need is that the attribute can only be increased. So if its initial value is 5, an update MOD/REPL '6' is valid and applied, while MOD/REPL '3' is invalid and rejected/ignored. Also being in MMR, the attribute can be updated on several instances. The current approach is to create a BE_PREOP or BE_TXN_PREOP plugin. This allow to retrieve the current value from the pblock (SLAPI_ENTRY_PRE_OP) and guaranties the value is exact as only one operation is processed at a time. The plugin registers a mod operation callback. It controls the new_value vs current_value to check that new_value >current_value. The plugin will update the mods. In particular translates a MOD/REPL into a MOD/DEL(current value) + MOD/ADD(new_value). Regarding the change of the MODS (mod/repl -> mod/del + mod/add), the plugin should be a BE_PREOP. This is because MODS are applied after BE_PREOP plugins, then new MODS added by BE_TXN_PREOP plugins are applied. A BE_TXN_PREOP plugin may translate mod/repl -> mod/del+mod/add but it is too late, mod/repl has already been applied after BE_PREOP plugins were called. Regarding replication, for non replicated updates, it should just reject (unwilling to perform) ops with new_value < current_value. For replicated update I see the two cases ([server / csn / attribute value] ): [A/csnA/valueA], [B/csnB/valueB] and the expected final value is ValueB+csnB 1. csnA < csnB and ValueA < ValueB. 1. When server A receives csnB/valueB, this is fine as ValueB>ValueA. But to know that ValueB will be selected the plugin needs to check that csnB>csnA. 1. When server B receives csnA/valueA it has 3 possibilities: 1. reject (unwilling to perform) the update. But then replication A->B will fail indefinitely 2. erase the update. For example the plugin could erase the mod from the set of mod. 3. let the operation continue because csnA < csnB, the kept value will be ValueB. Here again the plugin needs to check csnA vs csnB 2. csnA > csnB and ValueA < ValueB. 1. When server A receives csnB/valueB, this is fine as ValueB>ValueA. But to know that ValueB will be selected the plugin need to check that csnB>csnA. 2. When server B receives csnA/valueA it has 2 possibilities: 1. reject (unwilling to perform) the update. But then replication A->B will fail indefinitely 2. erase the update. For example the plugin could erase the mod from the set of mod. So I think the plugin should not rely on the new_value present in the operation but rather computes the final_value (taking into account the CSN). If the final_value > current_value, it let the operation going on (even if the new_value in the operation < current_value). If the final_value < current_value it should remove the mod from the mods (2.2.2) and likely log a message.
What happens if ValueA == ValueB and csnA != csnB? Do we want to allow the same value to be issued by two different servers? Is this a case as with DNA and uidNumber, that we assign servers to have ranges?
That is a good question and so far I still need confirmation. This is a case with OTP updating the HOTPcounter/TOTPwatermark. If a bind happens with a given new HOTPcounter value, it will trigger internal mod on an entry (related to bindDN) to update this counter. IMHO we can have parallel bind with a same counter, this on different or on the same server as well. In both cases, the csn will be different but the value identical.
thanks Rich thierry
Changing MOD/REPL into MOD/DEL+ MOD/ADD is a possibility but the attribute being single valued I think it is not mandatory. Thanks thierry
-- 389-devel mailing list 389-devel@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/389-devel
-- 389-devel mailing list 389-devel@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/389-devel
389-devel@lists.fedoraproject.org