From 43397d1317cf322f368ba050d042167914975525 Mon Sep 17 00:00:00 2001 From: unknown <627433532@qq.com> Date: Sun, 26 Oct 2025 09:42:11 +0800 Subject: [PATCH 1/2] =?UTF-8?q?trash=E6=94=B9=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/zerows/cosmic/StubServerService.java | 2 +- .../io/zerows/plugins/trash/TrashAddOn.java | 2 +- .../io/zerows/plugins/trash/TrashClient.java | 57 +++- .../zerows/plugins/trash/TrashClientImpl.java | 243 ++++++++++++++++-- .../zerows/plugins/trash/exception/ERR.java | 12 + .../_60034Exception500SharedDataMode.java | 13 + .../_60035Exception500PoolInternal.java | 13 + 7 files changed, 319 insertions(+), 23 deletions(-) create mode 100644 zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/exception/ERR.java create mode 100644 zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/exception/_60034Exception500SharedDataMode.java create mode 100644 zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/exception/_60035Exception500PoolInternal.java diff --git a/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/StubServerService.java b/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/StubServerService.java index d1c02d32..efd7a4e0 100644 --- a/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/StubServerService.java +++ b/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/StubServerService.java @@ -108,7 +108,7 @@ class StubServerService extends AbstractAmbiguity implements StubServer { log.debug("[ ZERO ] 二次检查命中:复用 RunServer -> {}", serverName); } - final long totalMs = (System.nanoTime() - c0) / 1_000_000; + final long totalMs = (System.nanoTime() - c0) / 10_000_000; log.debug("[ ZERO ] 创建流程完成(锁内)-> name={}, criticalMs={}ms", serverName, totalMs); promise.complete(runServer); diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/TrashAddOn.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/TrashAddOn.java index 64007610..37da17a3 100644 --- a/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/TrashAddOn.java +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/TrashAddOn.java @@ -36,6 +36,6 @@ class TrashAddOn extends AddOnBase { @Override protected TrashClient createInstanceBy(final String name) { - return TrashClient.createClient(this.vertx(), this.config()); + return TrashClient.createClient(this.vertx(), name); } } diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/TrashClient.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/TrashClient.java index 10fa7760..d80c0ed2 100644 --- a/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/TrashClient.java +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/TrashClient.java @@ -1,21 +1,25 @@ package io.zerows.plugins.trash; -import io.vertx.core.Future; -import io.vertx.core.MultiMap; -import io.vertx.core.Vertx; +import io.r2mo.typed.common.Kv; +import io.vertx.codegen.annotations.Fluent; +import io.vertx.core.*; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; +import io.zerows.sdk.plugins.AddOn; import io.zerows.specification.configuration.HConfig; +import java.util.Set; + /* * Trash Client for * 1) backup * 2) restore */ +@AddOn.Name("DEFAULT_TRASH_CLIENT") public interface TrashClient { - static TrashClient createClient(final Vertx vertx, final HConfig config) { - return new TrashClientImpl(vertx, config); + static TrashClient createClient(final Vertx vertx, final String name) { + return TrashClientImpl.create(vertx, name); } /* @@ -33,4 +37,47 @@ public interface TrashClient { * Restore record for each deleting */ Future restoreAsync(String identifier, JsonObject record, MultiMap params); + + Kv put(K key, V value); + + Kv put(K key, V value, int expiredSecs); + + Kv remove(K key); + + V get(K key); + + V get(K key, boolean once); + + boolean clear(); + + int size(); + + Set keys(); + + @Fluent + TrashClient put(K key, V value, Handler>> handler); + + @Fluent + TrashClient put(K key, V value, int expiredSecs, Handler>> handler); + + @Fluent + TrashClient remove(K key, Handler>> handler); + + @Fluent + TrashClient get(K key, Handler> handler); + + @Fluent + TrashClient get(K key, boolean once, Handler> handler); + + @Fluent + TrashClient clear(Handler> handler); + + /* + * Map count for usage + */ + @Fluent + TrashClient size(Handler> handler); + + @Fluent + TrashClient keys(Handler>> handler); } diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/TrashClientImpl.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/TrashClientImpl.java index 80619d4f..e9524166 100644 --- a/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/TrashClientImpl.java +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/TrashClientImpl.java @@ -1,42 +1,78 @@ package io.zerows.plugins.trash; -import io.vertx.core.Future; -import io.vertx.core.MultiMap; -import io.vertx.core.Vertx; +import io.r2mo.typed.cc.Cc; +import io.r2mo.typed.common.Kv; +import io.r2mo.typed.exception.WebException; +import io.vertx.core.*; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; +import io.vertx.core.shareddata.AsyncMap; +import io.vertx.core.shareddata.LocalMap; +import io.vertx.core.shareddata.SharedData; +import io.zerows.epoch.annotations.Defer; +import io.zerows.plugins.trash.exception._60034Exception500SharedDataMode; import io.zerows.specification.configuration.HConfig; import io.zerows.support.Ut; +import lombok.extern.slf4j.Slf4j; import java.util.Objects; +import java.util.Set; +@Defer +@Slf4j class TrashClientImpl implements TrashClient { - private final transient Vertx vertxRef; + private final transient Vertx vertx; private final JsonObject options = new JsonObject(); - public TrashClientImpl(final Vertx vertxRef, final HConfig config) { - this.vertxRef = vertxRef; - Objects.requireNonNull(config, "[ ZERO ] Actor 是必须配置的,所以 config 不可能为空!"); - if (Objects.nonNull(config.options())) { - this.options.mergeIn(config.options(), true); - } + private final transient String poolName; + private static final Cc CC_CLIENTS = Cc.open(); + TrashClientImpl(final Vertx vertx, final String name) { + this.vertx = vertx; + this.poolName = name; + } + public static TrashClient create(final Vertx vertx, final String name) { + return CC_CLIENTS.pick(() -> new TrashClientImpl(vertx, name), name); + } + + private void async(final Handler>> handler) { + final SharedData sd = this.vertx.sharedData(); + // Async map created + log.info("[ ZERO ] ( Async ) 你正在使用异步模式创建 AsyncMap,开始单例化."); + sd.getAsyncMap(this.poolName).onComplete(res -> { + if (res.succeeded()) { + log.info("[ ZERO ] ( Async ) AsyncMap 初始化完成,{} = {}.", + this.poolName, String.valueOf(res.result().hashCode())); + handler.handle(Future.succeededFuture(res.result())); + } else { + final WebException error = new _60034Exception500SharedDataMode(res.cause()); + handler.handle(Future.failedFuture(error)); + } + }); } + private LocalMap sync() { + final SharedData sd = this.vertx.sharedData(); + // Sync map created + final LocalMap localMap = sd.getLocalMap(this.poolName); + log.info("[ ZERO ] ( Sync ) 你正在使用同步模式创建 LocalMap, {} = {}.", + this.poolName, String.valueOf(localMap.hashCode())); + return localMap; + } @Override public Future backupAsync(final String identifier, final JsonObject record, final MultiMap params) { final JsonObject content = Ut.valueJObject(record); - if (Ut.isNotNil(content)) { - TrashBuilder.of(identifier, this.options).createHistory(record, params); - } +// if (Ut.isNotNil(content)) { +// TrashBuilder.of(identifier, this.options).createHistory(record, params); +// } return Future.succeededFuture(record); } @Override public Future backupAsync(final String identifier, final JsonArray records, final MultiMap params) { final JsonArray content = Ut.valueJArray(records); - if (!content.isEmpty()) { - TrashBuilder.of(identifier, this.options).createHistory(content, params); - } +// if (!content.isEmpty()) { +// TrashBuilder.of(identifier, this.options).createHistory(content, params); +// } return Future.succeededFuture(records); } @@ -57,4 +93,179 @@ class TrashClientImpl implements TrashClient { */ return null; } + @Override + public Kv put(final K key, final V value) { + final V reference = this.sync().get(key); + // Add & Replace + if (Objects.isNull(reference)) { + this.sync().put(key, value); + } else { + this.sync().replace(key, value); + } + return Kv.create(key, value); + } + + @Override + public Kv put(final K key, final V value, final int seconds) { + Kv result = this.put(key, value); + log.info("[ ZERO ] ( Timer ) {} = {} 已添加到 LocalMap, 持续 {} 秒.", key, value, String.valueOf(seconds)); + this.vertx.setTimer(seconds * 1000, id -> { + final V existing = this.get(key); + if (Objects.nonNull(existing)) { + log.info("[ ZERO ] ( Timer ) LocalMap, key = {} 已过期,数据已移除.", key); + this.remove(key); + } else { + log.info("[ ZERO ] ( Timer ) LocalMap, key = {} 已被移除.", key); + } + }); + return result; + } + + @Override + public TrashClient put(final K key, final V value, + final Handler>> handler) { + this.async(map -> map.result().get(key).onComplete(res -> { + if (res.succeeded()) { + final V reference = res.result(); + if (Objects.isNull(reference)) { + map.result() + .put(key, value).onComplete(added -> this.putHandler(added, key, value, handler)); + } else { + map.result() + .replace(key, value).onComplete(replaced -> this.putHandler(replaced, key, value, handler)); + } + } else { + final WebException error = new _60034Exception500SharedDataMode(res.cause()); + handler.handle(Future.failedFuture(error)); + } + })); + return this; + } + + @Override + public TrashClient put(final K key, final V value, final int seconds, + final Handler>> handler) { + log.info("[ ZERO ] ( Timer ) {} = {} 已添加到 AsyncMap, 持续 {} 秒.", key, value, String.valueOf(seconds)); + final Integer ms = seconds * 1000; + this.async(map -> map.result().get(key).onComplete(res -> { + if (res.succeeded()) { + final V reference = res.result(); + if (Objects.isNull(reference)) { + map.result() + .put(key, value, ms).onComplete(added -> this.putHandler(added, key, value, handler)); + } else { + map.result() + .replace(key, value, ms).onComplete(replaced -> this.putHandler(replaced, key, value, handler)); + } + } else { + final WebException error = new _60034Exception500SharedDataMode(res.cause()); + handler.handle(Future.failedFuture(error)); + } + })); + return this; + } + + private void putHandler(final AsyncResult done, final K key, final V value, + final Handler>> handler) { + if (done.succeeded()) { + log.info("[ ZERO ] ( Timer ) AsyncMap, key = {} 已过期,数据已移除.", key); + handler.handle(Future.succeededFuture(Kv.create(key, value))); + } else { + final WebException error = new _60034Exception500SharedDataMode(done.cause()); + handler.handle(Future.failedFuture(error)); + } + } + + @Override + public Kv remove(final K key) { + final V removed = this.sync().remove(key); + return Kv.create(key, removed); + } + + @Override + public V get(final K key) { + return this.sync().get(key); + } + + @Override + public boolean clear() { + this.sync().clear(); + return true; + } + + @Override + public V get(final K key, final boolean once) { + final V value = this.get(key); + if (once) { + this.remove(key); + } + return value; + } + + @Override + public TrashClient remove(final K key, + final Handler>> handler) { + this.async(map -> map.result().remove(key).onComplete(res -> { + if (res.succeeded()) { + final V reference = res.result(); + handler.handle(Future.succeededFuture(Kv.create(key, reference))); + } else { + final WebException error = new _60034Exception500SharedDataMode(res.cause()); + handler.handle(Future.failedFuture(error)); + } + })); + return this; + } + + @Override + public TrashClient get(final K key, + final Handler> handler) { + this.async(map -> map.result().get(key).onComplete(handler)); + return this; + } + + @Override + public TrashClient get(K key, boolean once, + Handler> handler) { + final TrashClient reference = this.get(key, handler); + if (once) { + this.async(map -> map.result().remove(key).onComplete(handler)); + } + return reference; + } + + @Override + public TrashClient clear(Handler> handler) { + this.async(map -> map.result().clear().onComplete(result -> handler.handle(Future.succeededFuture(Boolean.TRUE)))); + return this; + } + + /* + * Shared Enhancement for + * + * 1) Session Management + * 2) Cache Management + * 3) Login/Logout Management + */ + @Override + public TrashClient size(Handler> handler) { + this.async(map -> map.result().size().onComplete(handler)); + return this; + } + + @Override + public TrashClient keys(Handler>> handler) { + this.async(map -> map.result().keys().onComplete(handler)); + return this; + } + + @Override + public int size() { + return this.sync().size(); + } + + @Override + public Set keys() { + return this.sync().keySet(); + } } diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/exception/ERR.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/exception/ERR.java new file mode 100644 index 00000000..57aeeac0 --- /dev/null +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/exception/ERR.java @@ -0,0 +1,12 @@ +package io.zerows.plugins.trash.exception; + +import io.netty.handler.codec.http.HttpResponseStatus; +import io.r2mo.vertx.common.exception.VertxE; + +/** + * @author lang : 2025-10-04 + */ +interface ERR { + VertxE _60034 = VertxE.of(-60034).state(HttpResponseStatus.INTERNAL_SERVER_ERROR); + VertxE _60035 = VertxE.of(-60035).state(HttpResponseStatus.INTERNAL_SERVER_ERROR); +} diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/exception/_60034Exception500SharedDataMode.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/exception/_60034Exception500SharedDataMode.java new file mode 100644 index 00000000..4f694156 --- /dev/null +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/exception/_60034Exception500SharedDataMode.java @@ -0,0 +1,13 @@ +package io.zerows.plugins.trash.exception; + +import io.r2mo.vertx.common.exception.VertxWebException; + +/** + * @author lang : 2025-09-30 + */ +public class _60034Exception500SharedDataMode extends VertxWebException { + + public _60034Exception500SharedDataMode(Throwable ex) { + super(ERR._60034, ex.getMessage()); + } +} diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/exception/_60035Exception500PoolInternal.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/exception/_60035Exception500PoolInternal.java new file mode 100644 index 00000000..16cc27bc --- /dev/null +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-trash/src/main/java/io/zerows/plugins/trash/exception/_60035Exception500PoolInternal.java @@ -0,0 +1,13 @@ +package io.zerows.plugins.trash.exception; + +import io.r2mo.vertx.common.exception.VertxWebException; + +/** + * @author lang : 2025-09-30 + */ +public class _60035Exception500PoolInternal extends VertxWebException { + + public _60035Exception500PoolInternal(final String name, final String method) { + super(ERR._60035, name, method); + } +} -- Gitee From ebc36c1cabce378bbf02b68f1c80cf0be849563b Mon Sep 17 00:00:00 2001 From: unknown <627433532@qq.com> Date: Sun, 26 Oct 2025 09:48:12 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=81=A2=E5=A4=8DStubServerService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/io/zerows/cosmic/StubServerService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/StubServerService.java b/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/StubServerService.java index efd7a4e0..d1c02d32 100644 --- a/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/StubServerService.java +++ b/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/StubServerService.java @@ -108,7 +108,7 @@ class StubServerService extends AbstractAmbiguity implements StubServer { log.debug("[ ZERO ] 二次检查命中:复用 RunServer -> {}", serverName); } - final long totalMs = (System.nanoTime() - c0) / 10_000_000; + final long totalMs = (System.nanoTime() - c0) / 1_000_000; log.debug("[ ZERO ] 创建流程完成(锁内)-> name={}, criticalMs={}ms", serverName, totalMs); promise.complete(runServer); -- Gitee