MarcGiffing / bucket4j-spring-boot-starter

Spring Boot Starter for Bucket4j

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bug in 0.5.0 w/ Hazelcast?

SledgeHammer01 opened this issue · comments

Tried upgrading to 7.0.0 & 0.5.0 builds. I'm using Servlet + Hazelcast.

Here you have:

But here you have:

AsyncCacheResolver implements CacheResolver, not SyncCacheResolver. So the servlet config never gets setup. This worked in 0.4.0 with 6.4.x.

The Servlet Filter has a blocking API. The condition for the SynchCacheResolver is correct. It will only activated if a non blocking cache is available. Bucket4J supports Hazelcast also with a non blocking API. Webflux is non-blocking and supports the AsyncCacheResolver.

Please try to configure Hazelcast with JCache. My configuration:

spring:
  cache:
    type: jcache
    jcache:
      provider: com.hazelcast.cache.impl.HazelcastServerCachingProvider
      config: classpath:hazelcast.xml
<?xml version="1.0" encoding="UTF-8"?>
<hazelcast xmlns="http://www.hazelcast.com/schema/config"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.hazelcast.com/schema/config
           http://www.hazelcast.com/schema/config/hazelcast-config-4.1.xsd">

    <map name="buckets">
		<time-to-live-seconds>120</time-to-live-seconds>
		<in-memory-format>BINARY</in-memory-format>
		<metadata-policy>CREATE_ON_UPDATE</metadata-policy>
		<statistics-enabled>true</statistics-enabled>
	</map>

	<cache name="buckets">
	</cache>

</hazelcast>

I had exactly the same situation where servlet config never gets set up.
I copied exactly the same HazelcastCacheResolver but implemented SyncCacheResolver rather than AsyncCacheResolver

@Component
public class HazelcastCacheResolver implements SyncCacheResolver {

    private HazelcastInstance hazelcastInstance;

    public HazelcastCacheResolver(HazelcastInstance hazelcastInstance) {
        this.hazelcastInstance = hazelcastInstance;
    }

    @Override
    public ProxyManager<String> resolve(String cacheName) {
        IMap<String, byte[]> map = hazelcastInstance.getMap(cacheName);
        return new HazelcastProxyManager<>(map);
    }

}

And configure to return the above bean

    @Bean
    public SyncCacheResolver rateLimitingBucketCacheResolver(HazelcastInstance hazelcastInstance) {
        return new HazelcastCacheResolver(hazelcastInstance);
    }

I am not an expert but the above solution is working for me.

My main point is to use Hazelcast directly rather than through JCache because direct usage of Hazelcast seems better than through JCache