nstream.reflect.model.LinkStats Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nstream-reflect Show documentation
Show all versions of nstream-reflect Show documentation
Web Agent introspection runtime
// Copyright 2015-2024 Nstream, inc.
//
// Licensed under the Redis Source Available License 2.0 (RSALv2) Agreement;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://redis.com/legal/rsalv2-agreement/
//
// 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 nstream.reflect.model;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import swim.recon.Recon;
import swim.structure.Form;
import swim.structure.Item;
import swim.structure.Kind;
import swim.structure.Record;
import swim.structure.Value;
import swim.system.LinkBinding;
import swim.warp.CommandMessage;
import swim.warp.Envelope;
import swim.warp.EventMessage;
@SuppressWarnings("checkstyle:VisibilityModifier")
public class LinkStats {
public volatile long downLinkCount;
public volatile long downMessageCount;
public volatile long downEventCount;
public volatile long downCommandCount;
public volatile long downMessageRateMax;
public volatile long upLinkCount;
public volatile long upMessageCount;
public volatile long upEventCount;
public volatile long upCommandCount;
public volatile long upCommandAvgSize;
public volatile long upMessageRateMax;
public LinkStats() {
// nop
}
public void didOpenDownlink(LinkBinding link) {
DOWN_LINK_COUNT.incrementAndGet(this);
}
public void didCloseDownlink(LinkBinding link) {
DOWN_LINK_COUNT.decrementAndGet(this);
}
public void didOpenUplink(LinkBinding link) {
UP_LINK_COUNT.incrementAndGet(this);
}
public void didCloseUplink(Value linkKey) {
UP_LINK_COUNT.decrementAndGet(this);
}
public void didPushDown(Envelope envelope) {
DOWN_MESSAGE_COUNT.incrementAndGet(this);
if (envelope instanceof EventMessage) {
DOWN_EVENT_COUNT.incrementAndGet(this);
} else if (envelope instanceof CommandMessage) {
DOWN_COMMAND_COUNT.incrementAndGet(this);
}
}
public void didPushUp(Envelope envelope) {
UP_MESSAGE_COUNT.incrementAndGet(this);
if (envelope instanceof EventMessage) {
UP_EVENT_COUNT.incrementAndGet(this);
} else if (envelope instanceof CommandMessage) {
long oldSize, oldCommandCount, delta, newSize;
do {
oldSize = this.upCommandAvgSize;
oldCommandCount = this.upCommandCount;
delta = Recon.sizeOf(envelope.body());
newSize = ((oldSize * oldCommandCount) + delta) / Math.max(1, oldCommandCount + 1);
} while (!UP_COMMAND_AVG_SIZE.compareAndSet(this, oldSize, newSize));
UP_COMMAND_COUNT.incrementAndGet(this);
}
}
public void accumulate(LinkStats stats) {
DOWN_LINK_COUNT.addAndGet(this, stats.downLinkCount);
DOWN_MESSAGE_COUNT.addAndGet(this, stats.downMessageCount);
DOWN_EVENT_COUNT.addAndGet(this, stats.downEventCount);
DOWN_COMMAND_COUNT.addAndGet(this, stats.downCommandCount);
DOWN_MESSAGE_RATE_MAX.addAndGet(this, stats.downMessageRateMax);
UP_LINK_COUNT.addAndGet(this, stats.upLinkCount);
UP_MESSAGE_COUNT.addAndGet(this, stats.upMessageCount);
UP_EVENT_COUNT.addAndGet(this, stats.upEventCount);
long oldSize, oldCommandCount, newSize;
do {
oldSize = this.upCommandAvgSize;
oldCommandCount = this.upCommandCount;
newSize = ((oldSize * oldCommandCount) + (stats.upCommandAvgSize * stats.upCommandCount))
/ Math.max(1, oldCommandCount + stats.upCommandCount);
} while (!UP_COMMAND_AVG_SIZE.compareAndSet(this, oldSize, newSize));
UP_COMMAND_COUNT.addAndGet(this, stats.upCommandCount);
UP_MESSAGE_RATE_MAX.addAndGet(this, stats.upMessageRateMax);
}
public void supersede(LinkStats total, LinkStats delta) {
final long newDownLinkCount = this.downLinkCount;
final long newDownMessageCount = this.downMessageCount;
final long newDownEventCount = this.downEventCount;
final long newDownCommandCount = this.downCommandCount;
final long newDownMessageRateMax = this.downMessageRateMax;
final long newUpLinkCount = this.upLinkCount;
final long newUpMessageCount = this.upMessageCount;
final long newUpEventCount = this.upEventCount;
final long newUpCommandAvgSize = this.upCommandAvgSize;
final long newUpCommandCount = this.upCommandCount;
final long newUpMessageRateMax = this.upMessageRateMax;
final long oldDownLinkCount = DOWN_LINK_COUNT.getAndSet(total, newDownLinkCount);
final long oldDownMessageCount = DOWN_MESSAGE_COUNT.getAndSet(total, newDownMessageCount);
final long oldDownEventCount = DOWN_EVENT_COUNT.getAndSet(total, newDownEventCount);
final long oldDownCommandCount = DOWN_COMMAND_COUNT.getAndSet(total, newDownCommandCount);
final long oldDownMessageRateMax = DOWN_MESSAGE_RATE_MAX.getAndSet(total, newDownMessageRateMax);
final long oldUpLinkCount = UP_LINK_COUNT.getAndSet(total, newUpLinkCount);
final long oldUpMessageCount = UP_MESSAGE_COUNT.getAndSet(total, newUpMessageCount);
final long oldUpEventCount = UP_EVENT_COUNT.getAndSet(total, newUpEventCount);
final long oldUpCommandAvgSize = UP_COMMAND_AVG_SIZE.getAndSet(total, newUpCommandAvgSize);
final long oldUpCommandCount = UP_COMMAND_COUNT.getAndSet(total, newUpCommandCount);
final long oldUpMessageRateMax = UP_MESSAGE_RATE_MAX.getAndSet(total, newUpMessageRateMax);
DOWN_LINK_COUNT.addAndGet(delta, newDownLinkCount - oldDownLinkCount);
DOWN_MESSAGE_COUNT.addAndGet(delta, newDownMessageCount - oldDownMessageCount);
DOWN_EVENT_COUNT.addAndGet(delta, newDownEventCount - oldDownEventCount);
DOWN_COMMAND_COUNT.addAndGet(delta, newDownCommandCount - oldDownCommandCount);
DOWN_MESSAGE_RATE_MAX.addAndGet(delta, newDownMessageRateMax - oldDownMessageRateMax);
UP_LINK_COUNT.addAndGet(delta, newUpLinkCount - oldUpLinkCount);
UP_MESSAGE_COUNT.addAndGet(delta, newUpMessageCount - oldUpMessageCount);
UP_EVENT_COUNT.addAndGet(delta, newUpEventCount - oldUpEventCount);
UP_COMMAND_AVG_SIZE.addAndGet(delta, newUpCommandAvgSize - oldUpCommandAvgSize);
UP_COMMAND_COUNT.addAndGet(delta, newUpCommandCount - oldUpCommandCount);
UP_MESSAGE_RATE_MAX.addAndGet(delta, newUpMessageRateMax - oldUpMessageRateMax);
}
public LinkStats getAndReset() {
final LinkStats stats = new LinkStats();
stats.downLinkCount = DOWN_LINK_COUNT.getAndSet(this, 0L);
stats.downMessageCount = DOWN_MESSAGE_COUNT.getAndSet(this, 0L);
stats.downEventCount = DOWN_EVENT_COUNT.getAndSet(this, 0L);
stats.downCommandCount = DOWN_COMMAND_COUNT.getAndSet(this, 0L);
final long downMessageRateMax = this.downMessageRateMax;
if (stats.downMessageCount > downMessageRateMax) {
stats.downMessageRateMax = stats.downMessageCount - downMessageRateMax;
DOWN_MESSAGE_RATE_MAX.set(this, stats.downMessageCount);
}
stats.upLinkCount = UP_LINK_COUNT.getAndSet(this, 0L);
stats.upMessageCount = UP_MESSAGE_COUNT.getAndSet(this, 0L);
stats.upEventCount = UP_EVENT_COUNT.getAndSet(this, 0L);
stats.upCommandAvgSize = UP_COMMAND_AVG_SIZE.getAndSet(this, 0L);
stats.upCommandCount = UP_COMMAND_COUNT.getAndSet(this, 0L);
final long upMessageRateMax = this.upMessageRateMax;
if (stats.upMessageCount > upMessageRateMax) {
stats.upMessageRateMax = stats.upMessageCount - upMessageRateMax;
UP_MESSAGE_RATE_MAX.set(this, stats.upMessageCount);
}
return stats;
}
public LinkStats get() {
final LinkStats stats = new LinkStats();
stats.downLinkCount = this.downLinkCount;
stats.downMessageCount = this.downMessageCount;
stats.downEventCount = this.downEventCount;
stats.downCommandCount = this.downCommandCount;
stats.downMessageRateMax = this.downMessageRateMax;
stats.upLinkCount = this.upLinkCount;
stats.upMessageCount = this.upMessageCount;
stats.upEventCount = this.upEventCount;
stats.upCommandCount = this.upCommandCount;
stats.upCommandAvgSize = this.upCommandAvgSize;
stats.upMessageRateMax = this.upMessageRateMax;
return stats;
}
public Value toValue() {
return form().mold(this).toValue();
}
static final AtomicLongFieldUpdater DOWN_LINK_COUNT =
AtomicLongFieldUpdater.newUpdater(LinkStats.class, "downLinkCount");
static final AtomicLongFieldUpdater DOWN_MESSAGE_COUNT =
AtomicLongFieldUpdater.newUpdater(LinkStats.class, "downMessageCount");
static final AtomicLongFieldUpdater DOWN_EVENT_COUNT =
AtomicLongFieldUpdater.newUpdater(LinkStats.class, "downEventCount");
static final AtomicLongFieldUpdater DOWN_COMMAND_COUNT =
AtomicLongFieldUpdater.newUpdater(LinkStats.class, "downCommandCount");
static final AtomicLongFieldUpdater DOWN_MESSAGE_RATE_MAX =
AtomicLongFieldUpdater.newUpdater(LinkStats.class, "downMessageRateMax");
static final AtomicLongFieldUpdater UP_LINK_COUNT =
AtomicLongFieldUpdater.newUpdater(LinkStats.class, "upLinkCount");
static final AtomicLongFieldUpdater UP_MESSAGE_COUNT =
AtomicLongFieldUpdater.newUpdater(LinkStats.class, "upMessageCount");
static final AtomicLongFieldUpdater UP_EVENT_COUNT =
AtomicLongFieldUpdater.newUpdater(LinkStats.class, "upEventCount");
static final AtomicLongFieldUpdater UP_COMMAND_COUNT =
AtomicLongFieldUpdater.newUpdater(LinkStats.class, "upCommandCount");
static final AtomicLongFieldUpdater UP_COMMAND_AVG_SIZE =
AtomicLongFieldUpdater.newUpdater(LinkStats.class, "upCommandAvgSize");
static final AtomicLongFieldUpdater UP_MESSAGE_RATE_MAX =
AtomicLongFieldUpdater.newUpdater(LinkStats.class, "upMessageRateMax");
private static Form form;
@Kind
public static Form form() {
if (form == null) {
form = new LinkStatsForm();
}
return form;
}
}
final class LinkStatsForm extends Form {
@Override
public Class> type() {
return LinkStats.class;
}
@Override
public Item mold(LinkStats stats) {
if (stats != null) {
final Record record = Record.create(12);
if (stats.downLinkCount > 0L) {
record.slot("downLinkCount", stats.downLinkCount);
}
if (stats.downMessageCount > 0L) {
record.slot("downMessageCount", stats.downMessageCount);
}
if (stats.downEventCount > 0L) {
record.slot("downEventCount", stats.downEventCount);
}
if (stats.downCommandCount > 0L) {
record.slot("downCommandCount", stats.downCommandCount);
}
if (stats.downMessageRateMax > 0L) {
record.slot("downMessageRateMax", stats.downMessageRateMax);
}
if (stats.upLinkCount > 0L) {
record.slot("upLinkCount", stats.upLinkCount);
}
if (stats.upMessageCount > 0L) {
record.slot("upMessageCount", stats.upMessageCount);
}
if (stats.upEventCount > 0L) {
record.slot("upEventCount", stats.upEventCount);
}
if (stats.upCommandCount > 0L) {
record.slot("upCommandCount", stats.upCommandCount);
record.slot("upCommandSize", stats.upCommandCount * stats.upCommandAvgSize);
record.slot("upCommandAvgSize", stats.upCommandAvgSize);
}
if (stats.upMessageRateMax > 0L) {
record.slot("upMessageRateMax", stats.upMessageRateMax);
}
return record;
} else {
return Item.extant();
}
}
@Override
public LinkStats cast(Item item) {
final Item value = item.toValue();
final LinkStats stats = new LinkStats();
stats.downLinkCount = value.get("downLinkCount").longValue(0L);
stats.downMessageCount = value.get("downMessageCount").longValue(0L);
stats.downEventCount = value.get("downEventCount").longValue(0L);
stats.downCommandCount = value.get("downCommandCount").longValue(0L);
stats.downMessageRateMax = value.get("downMessageRateMax").longValue(0L);
stats.upLinkCount = value.get("upLinkCount").longValue(0L);
stats.upMessageCount = value.get("upMessageCount").longValue(0L);
stats.upEventCount = value.get("upEventCount").longValue(0L);
stats.upCommandAvgSize = value.get("upCommandSize").longValue(0L) / value.get("upCommandCount").longValue(1L);
stats.upCommandCount = value.get("upCommandCount").longValue(0L);
stats.upMessageRateMax = value.get("upMessageRateMax").longValue(0L);
return stats;
}
}