Support of implicit configuration replacement for distributed use cases
See original GitHub issueThe problem that need be solved
Distributed bucket operates with configuration that was provided at the time of its creation. Providing the new configuration via RemoteBucketBuilder takes no effect if bucket is already exists in the persistent storage, because configuration is stored together with state of bucket. There is only one way to replace configuration of bucket - is explicit calling of replaceConfiguration or its async analog.
Explicit config replacement can be awkward in the following cases:
- It requires for library client to write the code for configuration replacement. It is unnecessary job, that is especially hard when bucket4j is used behind of high-level frameworks like bucket4j-spring-boot-starter, when end-clients are not mentally prepared to work directly with low-level API of Bucket4j.
- It can confuse the user in the following scenario: user stores limits in the configuration for example in proerties or yaml file, user updates configuration files and restarts application and he becomes surprised because new limits are not applied for buckets that survive application restart in the storage, because as was mentioned above only one way to change the config for already persisted bucket is explicitly calling of
replaceConfiguration
for each persisted bucket. - For some persistent technologies like Redis it is costly to identify all buckets that are persisted in the storage, because lack of mechanisms for grouping like tables or caches leads to scan all keys, even keys that points to data that not related to rate-limiting
The solution:
It is enough to introduce configuration version concept. When bucket detects that persisted configuration version is less that provided through builder API then persisted configuration should be automatically replaced without disturbing the client, so all that needs from client is providing new version and new configuration and all necessary work will be done automatically. Already existed methods for builder API should use “0” as version, and replace configuration methods should not change the configuration version.
Required API changes:
- Introduce new methods to RemoteBucketBuilder API:
/**
* Activates implicit configuration replacement.
*
* <p> By default distributed bucket operates with configuration that was provided at the time of its first creation.
* Providing the new configuration via {@link RemoteBucketBuilder} takes no effect if bucket is already persisted in the storage, because configuration is stored together with state of bucket.
* Without implicit configuration replacement, there is only one way to replace configuration of bucket - is explicit calling of {@link io.github.bucket4j.Bucket#replaceConfiguration(BucketConfiguration, TokensInheritanceStrategy)}.
*
* <p>
* When implicit configuration replacement is activated, bucket will check that version of configuration in the storage >= than provided {@code desiredConfigurationVersion},
* and automatically replace persisted configuration using provided {@code tokensInheritanceStrategy} in case of persisted configuration is obsolete.
*
* @param desiredConfigurationVersion specifies desired configuration version
* @param tokensInheritanceStrategy the strategy that will be used for token migration if {@code desiredConfigurationVersion of persisted bucket} is less that provided desiredConfigurationVersion
*
* @return {@code this}
*/
RemoteBucketBuilder<K> withImplicitConfigurationReplacement(long desiredConfigurationVersion, TokensInheritanceStrategy tokensInheritanceStrategy);
- Apply similar changes to RemoteAsyncBucketBuilder:
/**
* Activates implicit configuration replacement.
*
* <p> By default distributed bucket operates with configuration that was provided at the time of its first creation.
* Providing the new configuration via {@link RemoteBucketBuilder} takes no effect if bucket is already persisted in the storage, because configuration is stored together with state of bucket.
* Without implicit configuration replacement, there is only one way to replace configuration of bucket - is explicit calling of {@link AsyncBucketProxy#replaceConfiguration(BucketConfiguration, TokensInheritanceStrategy)}.
*
* <p>
* When implicit configuration replacement is activated, bucket will check that version of configuration in the storage >= than provided {@code desiredConfigurationVersion},
* and automatically replace persisted configuration using provided {@code tokensInheritanceStrategy} in case of persisted configuration is obsolete.
*
* @param desiredConfigurationVersion specifies desired configuration version
* @param tokensInheritanceStrategy the strategy that will be used for token migration if {@code desiredConfigurationVersion of persisted bucket} is less that provided desiredConfigurationVersion
*
* @return {@code this}
*/
RemoteAsyncBucketBuilder<K> withImplicitConfigurationReplacement(long desiredConfigurationVersion, TokensInheritanceStrategy tokensInheritanceStrategy);
Issue Analytics
- State:
- Created a year ago
- Reactions:1
- Comments:5
Top GitHub Comments
Hello @SGERASIMOV
Yes. Work is in progress currently, it just has not been pushed yet just because of intermediate state. I expect that it will be completed at August.
Has been released with version 8.1.0 Documentation can be found there https://bucket4j.com/8.1.0/toc.html#implicit-configuration-replacement