diff --git a/src/main/java/net/joelinn/quartz/jobstore/AbstractRedisStorage.java b/src/main/java/net/joelinn/quartz/jobstore/AbstractRedisStorage.java index acb75ff..daacb39 100644 --- a/src/main/java/net/joelinn/quartz/jobstore/AbstractRedisStorage.java +++ b/src/main/java/net/joelinn/quartz/jobstore/AbstractRedisStorage.java @@ -326,6 +326,8 @@ public List getTriggersForJob(JobKey jobKey, T jedis) throws Jo * @throws org.quartz.JobPersistenceException if the unset operation failed */ public abstract boolean unsetTriggerState(final String triggerHashKey, T jedis) throws JobPersistenceException; + public abstract boolean unsetTriggerState(final String triggerHashKey, RedisTriggerState excludeState, T jedis) throws JobPersistenceException; + /** * Set a trigger state by adding the trigger to the relevant sorted set, using its next fire time as the score. @@ -339,8 +341,12 @@ public List getTriggersForJob(JobKey jobKey, T jedis) throws Jo public boolean setTriggerState(final RedisTriggerState state, final double score, final String triggerHashKey, T jedis) throws JobPersistenceException{ boolean success = false; if(state != null){ - unsetTriggerState(triggerHashKey, jedis); + //BUG FIX, delete all the key first, and then add new may leading to lost trigger, if the service restart at that moment + //So we need to add first, and delete later -gs + //unsetTriggerState(triggerHashKey, jedis); success = jedis.zadd(redisSchema.triggerStateKey(state), score, triggerHashKey) == 1; + unsetTriggerState(triggerHashKey, state, jedis); + } return success; } diff --git a/src/main/java/net/joelinn/quartz/jobstore/RedisClusterStorage.java b/src/main/java/net/joelinn/quartz/jobstore/RedisClusterStorage.java index 6ba265b..48c7cac 100644 --- a/src/main/java/net/joelinn/quartz/jobstore/RedisClusterStorage.java +++ b/src/main/java/net/joelinn/quartz/jobstore/RedisClusterStorage.java @@ -256,6 +256,26 @@ public boolean unsetTriggerState(String triggerHashKey, JedisClusterCommandsWrap return removed; } + @Override + public boolean unsetTriggerState(String triggerHashKey, RedisTriggerState excludeState, JedisClusterCommandsWrapper jedis) throws JobPersistenceException { + boolean removed = false; + List responses = new ArrayList<>(RedisTriggerState.values().length); + for (RedisTriggerState state : RedisTriggerState.values()) { + if (state.name().equalsIgnoreCase(excludeState.name())){ + continue; + } + responses.add(jedis.zrem(redisSchema.triggerStateKey(state), triggerHashKey)); + } + for (Long response : responses) { + removed = response == 1; + if (removed) { + jedis.del(redisSchema.triggerLockKey(redisSchema.triggerKey(triggerHashKey))); + break; + } + } + return removed; + } + /** * Store a {@link Calendar} * diff --git a/src/main/java/net/joelinn/quartz/jobstore/RedisStorage.java b/src/main/java/net/joelinn/quartz/jobstore/RedisStorage.java index d6b079b..efe2f10 100644 --- a/src/main/java/net/joelinn/quartz/jobstore/RedisStorage.java +++ b/src/main/java/net/joelinn/quartz/jobstore/RedisStorage.java @@ -273,6 +273,29 @@ public boolean unsetTriggerState(final String triggerHashKey, Jedis jedis) throw return removed; } + @Override + public boolean unsetTriggerState(final String triggerHashKey,RedisTriggerState excludeState, Jedis jedis) throws JobPersistenceException { + boolean removed = false; + Pipeline pipe = jedis.pipelined(); + List> responses = new ArrayList<>(RedisTriggerState.values().length); + for (RedisTriggerState state : RedisTriggerState.values()) { + if (state.name().equalsIgnoreCase(excludeState.name())){ + continue; + } + responses.add(pipe.zrem(redisSchema.triggerStateKey(state), triggerHashKey)); + } + + pipe.sync(); + for (Response response : responses) { + removed = response.get() == 1; + if(removed){ + jedis.del(redisSchema.triggerLockKey(redisSchema.triggerKey(triggerHashKey))); + break; + } + } + return removed; + } + /** * Store a {@link org.quartz.Calendar} * @param name the name of the calendar