From 629d84faec617708d621cbe2216e4137c2f05568 Mon Sep 17 00:00:00 2001 From: scottf Date: Thu, 5 Sep 2024 11:42:26 -0400 Subject: [PATCH] More stats and tracking support to multi Application --- .../main/java/io/nats/jsmulti/JsMulti.java | 2 +- .../java/io/nats/jsmulti/settings/Action.java | 2 +- .../io/nats/jsmulti/settings/Arguments.java | 2 +- .../io/nats/jsmulti/settings/Context.java | 2 +- .../io/nats/jsmulti/shared/ActionRunner.java | 13 ++ .../io/nats/jsmulti/shared/Application.java | 2 +- .../java/io/nats/jsmulti/shared/Debug.java | 13 ++ .../nats/jsmulti/shared/OptionsFactory.java | 2 +- .../java/io/nats/jsmulti/shared/RunStat.java | 203 ++++++++++++++++++ .../java/io/nats/jsmulti/shared/Stats.java | 140 ++++++++---- .../java/io/nats/jsmulti/shared/Usage.java | 2 +- .../java/io/nats/jsmulti/shared/Utils.java | 8 +- 12 files changed, 340 insertions(+), 51 deletions(-) create mode 100644 js-multi-tool/src/main/java/io/nats/jsmulti/shared/RunStat.java diff --git a/js-multi-tool/src/main/java/io/nats/jsmulti/JsMulti.java b/js-multi-tool/src/main/java/io/nats/jsmulti/JsMulti.java index 5087bd3..88b1c18 100644 --- a/js-multi-tool/src/main/java/io/nats/jsmulti/JsMulti.java +++ b/js-multi-tool/src/main/java/io/nats/jsmulti/JsMulti.java @@ -1,4 +1,4 @@ -// Copyright 2021-2022 The NATS Authors +// Copyright 2021-2024 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: diff --git a/js-multi-tool/src/main/java/io/nats/jsmulti/settings/Action.java b/js-multi-tool/src/main/java/io/nats/jsmulti/settings/Action.java index cdc2e66..c63bff9 100644 --- a/js-multi-tool/src/main/java/io/nats/jsmulti/settings/Action.java +++ b/js-multi-tool/src/main/java/io/nats/jsmulti/settings/Action.java @@ -1,4 +1,4 @@ -// Copyright 2021-2022 The NATS Authors +// Copyright 2021-2024 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: diff --git a/js-multi-tool/src/main/java/io/nats/jsmulti/settings/Arguments.java b/js-multi-tool/src/main/java/io/nats/jsmulti/settings/Arguments.java index d8f5ba8..8c202e0 100644 --- a/js-multi-tool/src/main/java/io/nats/jsmulti/settings/Arguments.java +++ b/js-multi-tool/src/main/java/io/nats/jsmulti/settings/Arguments.java @@ -1,4 +1,4 @@ -// Copyright 2021-2022 The NATS Authors +// Copyright 2021-2024 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: diff --git a/js-multi-tool/src/main/java/io/nats/jsmulti/settings/Context.java b/js-multi-tool/src/main/java/io/nats/jsmulti/settings/Context.java index bdbff6d..9e28bd7 100644 --- a/js-multi-tool/src/main/java/io/nats/jsmulti/settings/Context.java +++ b/js-multi-tool/src/main/java/io/nats/jsmulti/settings/Context.java @@ -1,4 +1,4 @@ -// Copyright 2021-2022 The NATS Authors +// Copyright 2021-2024 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: diff --git a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/ActionRunner.java b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/ActionRunner.java index f111f44..7ed255b 100644 --- a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/ActionRunner.java +++ b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/ActionRunner.java @@ -1,3 +1,16 @@ +// Copyright 2021-2024 The NATS Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package io.nats.jsmulti.shared; import io.nats.client.Connection; diff --git a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Application.java b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Application.java index 244634a..624ede0 100644 --- a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Application.java +++ b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Application.java @@ -1,4 +1,4 @@ -// Copyright 2021-2022 The NATS Authors +// Copyright 2021-2024 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: diff --git a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Debug.java b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Debug.java index 72c93fe..8586b45 100644 --- a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Debug.java +++ b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Debug.java @@ -1,3 +1,16 @@ +// Copyright 2021-2024 The NATS Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package io.nats.jsmulti.shared; import io.nats.client.Connection; diff --git a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/OptionsFactory.java b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/OptionsFactory.java index 32ae6e9..cd0566c 100644 --- a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/OptionsFactory.java +++ b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/OptionsFactory.java @@ -1,4 +1,4 @@ -// Copyright 2021-2022 The NATS Authors +// Copyright 2021-2024 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: diff --git a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/RunStat.java b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/RunStat.java new file mode 100644 index 0000000..6b0de67 --- /dev/null +++ b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/RunStat.java @@ -0,0 +1,203 @@ +// Copyright 2021-2024 The NATS Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package io.nats.jsmulti.shared; + +import io.nats.client.support.JsonValue; +import io.nats.client.support.JsonValueUtils; + +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryMXBean; +import java.lang.management.MemoryUsage; +import java.lang.management.ThreadMXBean; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static io.nats.jsmulti.shared.Utils.makeId; + +public class RunStat { + public final String id; + public final long maxMemory; + public final long allocatedMemory; + public final long freeMemory; + public final long heapInit; + public final long heapUsed; + public final long heapCommitted; + public final long heapMax; + public final long nonHeapInit; + public final long nonHeapUsed; + public final long nonHeapCommitted; + public final long nonHeapMax; + public final int threadCount; + public final List deadThreads; + public final List liveThreads; + + public RunStat() { + id = makeId(); + + MemoryMXBean memBean = ManagementFactory.getMemoryMXBean(); + ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); + Runtime runtime = Runtime.getRuntime(); + maxMemory = runtime.maxMemory(); + allocatedMemory = runtime.totalMemory(); + freeMemory = runtime.freeMemory(); + + System.out.println("Mem"); + MemoryUsage usage = memBean.getHeapMemoryUsage(); + heapInit = usage.getInit(); + heapUsed = usage.getUsed(); + heapCommitted = usage.getCommitted(); + heapMax = usage.getMax(); + + usage = memBean.getNonHeapMemoryUsage(); + nonHeapInit = usage.getInit(); + nonHeapUsed = usage.getUsed(); + nonHeapCommitted = usage.getCommitted(); + nonHeapMax = usage.getMax(); + + deadThreads = new ArrayList<>(); + liveThreads = new ArrayList<>(); + threadCount = threadBean.getThreadCount(); + long[] deadThreadIds = threadBean.findDeadlockedThreads(); + if (deadThreadIds == null) { + deadThreadIds = new long[0]; + } + for (long id : threadBean.getAllThreadIds()) { + String text = "<" + id + "> " + threadBean.getThreadInfo(id).getThreadName(); + if (isAlive(id, deadThreadIds)) { + liveThreads.add(text); + } + else { + deadThreads.add(text); + } + } + } + + public RunStat(JsonValue jv) { + id = JsonValueUtils.readString(jv, "id", null); + maxMemory = JsonValueUtils.readLong(jv, "maxMemory", 0); + allocatedMemory = JsonValueUtils.readLong(jv, "allocatedMemory", 0); + freeMemory = JsonValueUtils.readLong(jv, "freeMemory", 0); + heapInit = JsonValueUtils.readLong(jv, "heapInit", 0); + heapUsed = JsonValueUtils.readLong(jv, "heapUsed", 0); + heapCommitted = JsonValueUtils.readLong(jv, "heapCommitted", 0); + heapMax = JsonValueUtils.readLong(jv, "heapMax", 0); + nonHeapInit = JsonValueUtils.readLong(jv, "nonHeapInit", 0); + nonHeapUsed = JsonValueUtils.readLong(jv, "nonHeapUsed", 0); + nonHeapCommitted = JsonValueUtils.readLong(jv, "nonHeapCommitted", 0); + nonHeapMax = JsonValueUtils.readLong(jv, "nonHeapMax", 0); + threadCount = JsonValueUtils.readInteger(jv, "threadCount", 0); + deadThreads = JsonValueUtils.readStringList(jv, "deadThreads"); + liveThreads = JsonValueUtils.readStringList(jv, "liveThreads"); + } + + public Map toJsonValueMap() { + JsonValueUtils.ArrayBuilder deadBuilder = JsonValueUtils.arrayBuilder(); + for (String s : deadThreads) { + deadBuilder.add(s); + } + JsonValueUtils.ArrayBuilder liveBuilder = JsonValueUtils.arrayBuilder(); + for (String s : liveThreads) { + liveBuilder.add(s); + } + + return JsonValueUtils.mapBuilder() + .put("id", id) + .put("maxMemory", maxMemory) + .put("allocatedMemory", allocatedMemory) + .put("freeMemory", freeMemory) + .put("heapInit", heapInit) + .put("heapUsed", heapUsed) + .put("heapCommitted", heapCommitted) + .put("heapMax", heapMax) + .put("nonHeapInit", nonHeapInit) + .put("nonHeapUsed", nonHeapUsed) + .put("nonHeapCommitted", nonHeapCommitted) + .put("nonHeapMax", nonHeapMax) + .put("threadCount", threadCount) + .put("deadThreads", deadBuilder.toJsonValue()) + .put("liveThreads", liveBuilder.toJsonValue()) + .toJsonValue().map; + } + + private static boolean isAlive(long id, long[] deadThreadIds) { + for (long dead : deadThreadIds) { + if (dead == id) { + return false; + } + } + return true; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + RunStat runStat = (RunStat) o; + return maxMemory == runStat.maxMemory + && allocatedMemory == runStat.allocatedMemory + && freeMemory == runStat.freeMemory + && heapInit == runStat.heapInit + && heapUsed == runStat.heapUsed + && heapCommitted == runStat.heapCommitted + && heapMax == runStat.heapMax + && nonHeapInit == runStat.nonHeapInit + && nonHeapUsed == runStat.nonHeapUsed + && nonHeapCommitted == runStat.nonHeapCommitted + && nonHeapMax == runStat.nonHeapMax + && threadCount == runStat.threadCount + && id.equals(runStat.id) + && equivalent(deadThreads, runStat.deadThreads) + && equivalent(liveThreads, runStat.liveThreads); + } + + @Override + public int hashCode() { + int result = id.hashCode(); + result = 31 * result + Long.hashCode(maxMemory); + result = 31 * result + Long.hashCode(allocatedMemory); + result = 31 * result + Long.hashCode(freeMemory); + result = 31 * result + Long.hashCode(heapInit); + result = 31 * result + Long.hashCode(heapUsed); + result = 31 * result + Long.hashCode(heapCommitted); + result = 31 * result + Long.hashCode(heapMax); + result = 31 * result + Long.hashCode(nonHeapInit); + result = 31 * result + Long.hashCode(nonHeapUsed); + result = 31 * result + Long.hashCode(nonHeapCommitted); + result = 31 * result + Long.hashCode(nonHeapMax); + result = 31 * result + threadCount; + result = 31 * result + deadThreads.hashCode(); + result = 31 * result + liveThreads.hashCode(); + return result; + } + + private static boolean equivalent(List l1, List l2) + { + if (l1 == null || l1.isEmpty()) { + return l2 == null || l2.isEmpty(); + } + + if (l2 == null || l1.size() != l2.size()) { + return false; + } + + for (String s : l1) { + if (!l2.contains(s)) { + return false; + } + } + return true; + } +} diff --git a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Stats.java b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Stats.java index 2a535b6..bc7e209 100644 --- a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Stats.java +++ b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Stats.java @@ -2,22 +2,26 @@ import io.nats.client.Message; import io.nats.client.impl.Headers; +import io.nats.client.support.JsonValue; +import io.nats.client.support.JsonValueUtils; import io.nats.jsmulti.settings.Action; import io.nats.jsmulti.settings.Context; -import java.io.*; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; import java.nio.charset.StandardCharsets; import java.text.NumberFormat; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import static io.nats.jsmulti.shared.Utils.HDR_PUB_TIME; import static io.nats.jsmulti.shared.Utils.makeId; -public class Stats implements Serializable { - private static final long serialVersionUID = 1L; +public class Stats { private static final double MILLIS_PER_SECOND = 1000; private static final double NANOS_PER_MILLI = 1000000; @@ -44,9 +48,17 @@ public class Stats implements Serializable { private static final String LCSV_HEADER = "Publish Time,Server Time,Received Time,Publish to Server,Server to Consumer,Publish to Consumer\n"; + // Misc + public final String id; + public final String label; + public final String key; + + private String exceptionMessage; + + // running numbers private long elapsed = 0; private long bytes = 0; - private int messageCount = 0; + private long messageCount = 0; // latency private long messagePubToServerTimeElapsed = 0; @@ -65,29 +77,23 @@ public class Stats implements Serializable { // Time keeping private long milliNow; - // Misc - private final String id; - private final String hdrLabel; - public final String subject; - private String exceptionMessage; - - private transient final Context ctx; - private transient final ExecutorService countService = Executors.newSingleThreadExecutor(); - private transient final FileOutputStream lout; + private final Context ctx; + private final FileOutputStream lout; + private final ExecutorService countService = Executors.newSingleThreadExecutor(); public Stats() { - id = makeId("stats"); + id = makeId(); + label = ""; + key = ""; ctx = null; - hdrLabel = ""; - subject = ""; lout = null; } public Stats(Context ctx) throws IOException { - id = makeId("stats"); + id = makeId(); this.ctx = ctx; - hdrLabel = ctx.action.getLabel(); - subject = hdrLabel + "." + ctx.id + "." + id; + label = ctx.action.getLabel(); + key = label + "." + ctx.id + "." + id; if (ctx.lcsv == null) { lout = null; } @@ -97,6 +103,54 @@ public Stats(Context ctx) throws IOException { } } + public Stats(JsonValue jv) { + ctx = null; + lout = null; + id = JsonValueUtils.readString(jv, "id", null); + label = JsonValueUtils.readString(jv, "hdrLabel", null); + key = JsonValueUtils.readString(jv, "subject", null); + exceptionMessage = JsonValueUtils.readString(jv, "exceptionMessage", null); + elapsed = JsonValueUtils.readLong(jv, "elapsed", 0); + bytes = JsonValueUtils.readLong(jv, "bytes", 0); + messageCount = JsonValueUtils.readLong(jv, "messageCount", 0); + messagePubToServerTimeElapsed = JsonValueUtils.readLong(jv, "messagePubToServerTimeElapsed", 0); + messageServerToReceiverElapsed = JsonValueUtils.readLong(jv, "messageServerToReceiverElapsed", 0); + messageFullElapsed = JsonValueUtils.readLong(jv, "messageFullElapsed", 0); + messagePubToServerTimeElapsedForAverage = JsonValueUtils.readLong(jv, "messagePubToServerTimeElapsedForAverage", 0); + messageServerToReceiverElapsedForAverage = JsonValueUtils.readLong(jv, "messageServerToReceiverElapsedForAverage", 0); + messageFullElapsedForAverage = JsonValueUtils.readLong(jv, "messageFullElapsedForAverage", 0); + maxMessagePubToServerTimeElapsed = JsonValueUtils.readLong(jv, "maxMessagePubToServerTimeElapsed", 0); + maxMessageServerToReceiverElapsed = JsonValueUtils.readLong(jv, "maxMessageServerToReceiverElapsed", 0); + maxMessageFullElapsed = JsonValueUtils.readLong(jv, "maxMessageFullElapsed", 0); + minMessagePubToServerTimeElapsed = JsonValueUtils.readLong(jv, "minMessagePubToServerTimeElapsed", 0); + minMessageServerToReceiverElapsed = JsonValueUtils.readLong(jv, "minMessageServerToReceiverElapsed", 0); + minMessageFullElapsed = JsonValueUtils.readLong(jv, "minMessageFullElapsed", 0); + } + + public Map toJsonValueMap() { + return JsonValueUtils.mapBuilder() + .put("id", id) + .put("hdrLabel", label) + .put("subject", key) + .put("exceptionMessage", exceptionMessage) + .put("elapsed", elapsed) + .put("bytes", bytes) + .put("messageCount", messageCount) + .put("messagePubToServerTimeElapsed", messagePubToServerTimeElapsed) + .put("messageServerToReceiverElapsed", messageServerToReceiverElapsed) + .put("messageFullElapsed", messageFullElapsed) + .put("messagePubToServerTimeElapsedForAverage", messagePubToServerTimeElapsedForAverage) + .put("messageServerToReceiverElapsedForAverage", messageServerToReceiverElapsedForAverage) + .put("messageFullElapsedForAverage", messageFullElapsedForAverage) + .put("maxMessagePubToServerTimeElapsed", maxMessagePubToServerTimeElapsed) + .put("maxMessageServerToReceiverElapsed", maxMessageServerToReceiverElapsed) + .put("maxMessageFullElapsed", maxMessageFullElapsed) + .put("minMessagePubToServerTimeElapsed", minMessagePubToServerTimeElapsed) + .put("minMessageServerToReceiverElapsed", minMessageServerToReceiverElapsed) + .put("minMessageFullElapsed", minMessageFullElapsed) + .toJsonValue().map; + } + public void setException(Exception e){ exceptionMessage = e.getMessage(); } @@ -193,7 +247,7 @@ public static void report(Stats stats, String label, boolean header, boolean foo double bytesPerSecond = MILLIS_PER_SECOND * (stats.bytes) / (stats.elapsed); if (header) { out.println("\n" + REPORT_SEP_LINE); - out.printf(REPORT_LINE_HEADER, stats.hdrLabel); + out.printf(REPORT_LINE_HEADER, stats.label); out.println(REPORT_SEP_LINE); } out.printf(REPORT_LINE_FORMAT, label, @@ -209,7 +263,7 @@ public static void report(Stats stats, String label, boolean header, boolean foo public static void rttReport(Stats stats, String tlabel, boolean header, boolean footer, PrintStream out) { if (header) { out.println("\n" + RTT_REPORT_SEP_LINE); - out.printf(RTT_REPORT_LINE_HEADER, stats.hdrLabel); + out.printf(RTT_REPORT_LINE_HEADER, stats.label); out.println(RTT_REPORT_SEP_LINE); } out.printf(RTT_REPORT_LINE_FORMAT, tlabel, @@ -312,12 +366,21 @@ public static void report(List statList) { } public static void report(List statList, PrintStream out) { + report(statList, out, false); + } + + public static void report(List statList, boolean idAsColumnLabel) { + report(statList, System.out, idAsColumnLabel); + } + + public static void report(List statList, PrintStream out, boolean idAsColumnLabel) { Stats totalStats = total(statList); Context ctx = statList.get(0).ctx; if (ctx != null && ctx.action == Action.RTT) { for (int x = 0; x < statList.size(); x++) { - rttReport(statList.get(x), "Thread " + (x+1), x == 0, false, out); + Stats stats = statList.get(x); + rttReport(stats, mainLabel(x, idAsColumnLabel, stats), x == 0, false, out); } out.println(RTT_REPORT_SEP_LINE); rttReport(totalStats, "Total", false, true, out); @@ -325,25 +388,35 @@ public static void report(List statList, PrintStream out) { } for (int x = 0; x < statList.size(); x++) { - report(statList.get(x), "Thread " + (x+1), x == 0, false, out); + Stats stats = statList.get(x); + report(stats, mainLabel(x, idAsColumnLabel, stats), x == 0, false, out); } out.println(REPORT_SEP_LINE); report(totalStats, "Total", false, true, out); if (statList.get(0).messagePubToServerTimeElapsed > 0) { for (int x = 0; x < statList.size(); x++) { - ltReport(statList.get(x), "Thread " + (x+1), x == 0, false, out); + Stats stats = statList.get(x); + ltReport(stats, mainLabel(x, idAsColumnLabel, stats), x == 0, false, out); } out.println(LT_REPORT_SEP_LINE); ltReport(totalStats, "Total", false, true, out); for (int x = 0; x < statList.size(); x++) { - lmReport(statList.get(x), "Thread " + (x+1), x == 0, false, out); + Stats stats = statList.get(x); + lmReport(stats, mainLabel(x, idAsColumnLabel, stats), x == 0, false, out); } lmReport(totalStats, "Total", false, true, out); } } + private static String mainLabel(int x, boolean idAsColumnLabel, Stats stats) { + if (idAsColumnLabel) { + return stats.id; + } + return "Thread " + (x + 1); + } + public static String humanBytes(double bytes) { if (bytes < HUMAN_BYTES_BASE) { return String.format("%.2f b", bytes); @@ -375,21 +448,4 @@ public static String format3(Number n) { } return (f + ZEROS).substring(0, at + 3 + 1); } - - public static byte[] serialize(Stats stats) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream objectOutputStream = new ObjectOutputStream(baos); - objectOutputStream.writeObject(stats); - objectOutputStream.flush(); - objectOutputStream.close(); - return baos.toByteArray(); - } - - public static Stats deserialize(byte[] bytes) throws ClassNotFoundException, IOException { - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - ObjectInputStream objectInputStream = new ObjectInputStream(bais); - Stats stats = (Stats) objectInputStream.readObject(); - objectInputStream.close(); - return stats; - } } diff --git a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Usage.java b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Usage.java index af8145f..6b1356a 100644 --- a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Usage.java +++ b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Usage.java @@ -1,4 +1,4 @@ -// Copyright 2021-2022 The NATS Authors +// Copyright 2021-2024 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: diff --git a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Utils.java b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Utils.java index 2cd24a1..f234a7e 100644 --- a/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Utils.java +++ b/js-multi-tool/src/main/java/io/nats/jsmulti/shared/Utils.java @@ -1,4 +1,4 @@ -// Copyright 2021-2022 The NATS Authors +// Copyright 2021-2024 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: @@ -22,8 +22,12 @@ public abstract class Utils { public static final String HDR_PUB_TIME = "pt"; + public static String makeId() { + return NUID.nextGlobalSequence(); + } + public static String makeId(String name) { - return name + "-" + NUID.nextGlobalSequence(); + return name + NUID.nextGlobalSequence(); } public static void report(Context ctx, int total, String message) {