由akka actor调用时,CacheEvict / CachePut不起作用

时间:2018-11-30 14:23:01

标签: java spring caching akka spring-cache

该应用程序使用spring,akka和mongodb。 它使用spring缓存来存储在mongo中的某些设置。该键由设置对象中的4个元素组成。缓存值应在创建后的X秒钟内更新或收回。

这是缓存服务:

@Component
public class SettingsCacheService {

    @Cacheable(value = SETTINGS_CACHE_STORE, key = "{#k1, #k2, #k3, #k4}", sync = true)
    public Settings readSettings(ActorSystem actorSystem, String k1, String k2, String k3, String k4) {
        Settings settings = mongoUtils.getSettings(k1, k2, k3, k4);
        ActorRef actor = SettingsCacheEvictScheduler.getActor(actorSystem, this, k1, k2, k3, k4);
        actorSystem.scheduler().scheduleOnce(Duration.create(10000, TimeUnit.MILLISECONDS), new Runnable() {
            @Override
            public void run() {
                actor.tell(SettingsCacheEvictScheduler.MESSAGE, ActorRef.noSender());
            }
        }, actorSystem.dispatcher());
        return settings;
    }

    @CacheEvict(value = SETTINGS_CACHE_STORE, key = "{#k1, #k2, #k3, #k4}", beforeInvocation = true)
    public void cacheEvict(SettingsCacheEvictScheduler settingsCacheEvictScheduler, String k1,
                           String k2, String k3, String k4) {
        settingsCacheEvictScheduler.getSelf().tell(PoisonPill.getInstance(), ActorRef.noSender());
    }

}

还有我创建的akka​​调度程序,用于从缓存中逐出值:

public class SettingsCacheEvictScheduler extends UntypedAbstractActor {

    public final static String MESSAGE = "cacheEvict";

    private SettingsCacheService settingsCacheService;
    private String k1;
    private String k2;
    private String k3;
    private String k4;

    public SettingsCacheEvictScheduler(SettingsCacheService settingsCacheService, String k1,
                                       String k2, String k3, String k4) {
        this.settingsCacheService = settingsCacheService;
        this.k1 = k1;
        this.k2 = k2;
        this.k3 = k3;
        this.k4 = k4;
    }

    public static ActorRef getActor(ActorSystem remoteActorSystem, SettingsCacheService settingsCacheService,
                                    String k1, String k2, String k3, String k4) {
        return remoteActorSystem.actorOf(
                Props.create(SettingsCacheEvictScheduler.class, settingsCacheService, k1, k2,
                        k3, k4));
    }

    @Override
    public void onReceive(Object message) throws Throwable {
        if (MESSAGE.equals(message)) {
            settingsCacheService.cacheEvict(this, k1, k2, k3, k4);
        }
    }
}

我以调试模式运行该应用程序,并添加了Spring缓存的跟踪日志。 我可以看到在缓存中创建的值具有预期的由4个字符串组成的键。调度程序按预期方式工作,并按预期方式调用cacheEvict方法,但是缓存逐出不起作用,并且值仍保留在缓存中。

我可以看到此日志中的另一个缓存服务:

Invalidating cache key [myKey] for 

,但永远不要使用此缓存服务。我没有看到拦截器需要设置缓存服务,而拦截器却需要其他缓存(我可以调试)。

我可以通过调试模式和日志确认使用期望的键缓存了值

CacheInterceptor - Computed cache key '[k1, k2, k3, k4]' for operation...

我可以看到cacheEvict方法内的代码已执行,但@cacheEvict批注似乎被忽略了

我有以下问题: 是否可以将这样的cacheEvict方法与由4个字符串组成的键一起使用? Akka是否存在任何不兼容性?

我用cachePut而不是cacheEvict尝试了同样的方法,并且遇到了同样的问题。

0 个答案:

没有答案