From b2273fcf645879d564c2e5518f4172defdf82027 Mon Sep 17 00:00:00 2001 From: Ahoo Wang Date: Sat, 8 May 2021 00:41:04 +0800 Subject: [PATCH] add ServiceDiscovery#getInstance impl add ServiceDiscovery#getInstanceTtl impl --- .../redis/DiscoveryRedisScripts.java | 10 +++++++ .../redis/RedisServiceDiscovery.java | 18 +++++++++-- .../resources/discovery_get_instance_ttl.lua | 30 +++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 discovery/src/main/resources/discovery_get_instance_ttl.lua diff --git a/discovery/src/main/java/me/ahoo/govern/discovery/redis/DiscoveryRedisScripts.java b/discovery/src/main/java/me/ahoo/govern/discovery/redis/DiscoveryRedisScripts.java index 3242bc14..af1c29c1 100644 --- a/discovery/src/main/java/me/ahoo/govern/discovery/redis/DiscoveryRedisScripts.java +++ b/discovery/src/main/java/me/ahoo/govern/discovery/redis/DiscoveryRedisScripts.java @@ -14,6 +14,8 @@ public final class DiscoveryRedisScripts { public static final String REGISTRY_RENEW = "registry_renew.lua"; public static final String REGISTRY_SET_METADATA = "registry_set_metadata.lua"; public static final String DISCOVERY_GET_INSTANCES = "discovery_get_instances.lua"; + public static final String DISCOVERY_GET_INSTANCE = "discovery_get_instance.lua"; + public static final String DISCOVERY_GET_INSTANCE_TTL = "discovery_get_instance_ttl.lua"; public static final String SERVICE_STAT = "service_stat.lua"; public static CompletableFuture loadRegistryRegister(RedisScriptingAsyncCommands scriptingCommands) { @@ -36,6 +38,14 @@ public static CompletableFuture loadDiscoveryGetInstances(RedisScripting return RedisScripts.loadScript(DISCOVERY_GET_INSTANCES, scriptingCommands); } + public static CompletableFuture loadDiscoveryGetInstance(RedisScriptingAsyncCommands scriptingCommands) { + return RedisScripts.loadScript(DISCOVERY_GET_INSTANCE, scriptingCommands); + } + + public static CompletableFuture loadDiscoveryGetInstanceTtl(RedisScriptingAsyncCommands scriptingCommands) { + return RedisScripts.loadScript(DISCOVERY_GET_INSTANCE_TTL, scriptingCommands); + } + public static CompletableFuture loadServiceStat(RedisScriptingAsyncCommands scriptingCommands) { return RedisScripts.loadScript(SERVICE_STAT, scriptingCommands); } diff --git a/discovery/src/main/java/me/ahoo/govern/discovery/redis/RedisServiceDiscovery.java b/discovery/src/main/java/me/ahoo/govern/discovery/redis/RedisServiceDiscovery.java index 236400df..66d015a8 100644 --- a/discovery/src/main/java/me/ahoo/govern/discovery/redis/RedisServiceDiscovery.java +++ b/discovery/src/main/java/me/ahoo/govern/discovery/redis/RedisServiceDiscovery.java @@ -50,12 +50,26 @@ public CompletableFuture> getInstances(String namespace, S @Override public CompletableFuture getInstance(String namespace, String serviceId, String instanceId) { - return null; + return DiscoveryRedisScripts.loadDiscoveryGetInstance(redisCommands) + .thenCompose(sha -> { + RedisFuture> redisFuture = redisCommands.evalsha(sha, ScriptOutputType.MULTI, namespace, serviceId, instanceId); + return redisFuture; + }) + .thenApply(instanceData -> { + if (Objects.isNull(instanceData)) { + return null; + } + return ServiceInstanceCodec.decode(instanceData); + }); } @Override public CompletableFuture getInstanceTtl(String namespace, String serviceId, String instanceId) { - return null; + return DiscoveryRedisScripts.loadDiscoveryGetInstance(redisCommands) + .thenCompose(sha -> { + RedisFuture redisFuture = redisCommands.evalsha(sha, ScriptOutputType.INTEGER, namespace, serviceId, instanceId); + return redisFuture; + }); } @Override diff --git a/discovery/src/main/resources/discovery_get_instance_ttl.lua b/discovery/src/main/resources/discovery_get_instance_ttl.lua new file mode 100644 index 00000000..ced7fb44 --- /dev/null +++ b/discovery/src/main/resources/discovery_get_instance_ttl.lua @@ -0,0 +1,30 @@ +local namespace = KEYS[1]; +local serviceId = KEYS[2]; +local instanceId = KEYS[3]; +local instanceIdxKey = namespace .. ':svc_itc_idx:' .. serviceId; + +local function getInstanceKey(instanceId) + return namespace .. ":svc_itc:" .. instanceId; +end + +local function ensureNotExpired(instanceIdxKey, instanceId) + local instanceKey = getInstanceKey(instanceId); + local instanceTtl = redis.call("ttl", instanceKey); + -- -2: The key doesn't exist | -1: The key is fixed | >0: ttl(second) + if instanceTtl == -2 then + redis.call("srem", instanceIdxKey, instanceId); + redis.call("del", instanceKey); + redis.call("publish", instanceKey, "expired"); + end + + return instanceTtl; +end + +local instanceTtl = ensureNotExpired(instanceIdxKey, instanceId); +if instanceTtl == -1 or instanceTtl == -2 then + return instanceTtl; +else + local nowTime = redis.call('time')[1]; + local ttlAt = nowTime + instanceTtl; + return ttlAt; +end