Time fs and peripheral operations

This commit is contained in:
Jonathan Coates 2022-12-15 22:12:53 +00:00
parent eeac86b07c
commit 4fa7f50534
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
8 changed files with 77 additions and 42 deletions

View File

@ -102,8 +102,7 @@ private FileSystem getFileSystem() {
*/
@LuaFunction
public final String[] list(String path) throws LuaException {
environment.observe(Metrics.FS_OPS);
try {
try (var ignored = environment.time(Metrics.FS_OPS)) {
return getFileSystem().list(path);
} catch (FileSystemException e) {
throw new LuaException(e.getMessage());
@ -184,7 +183,7 @@ public final String getDir(String path) {
*/
@LuaFunction
public final long getSize(String path) throws LuaException {
try {
try (var ignored = environment.time(Metrics.FS_OPS)) {
return getFileSystem().getSize(path);
} catch (FileSystemException e) {
throw new LuaException(e.getMessage());
@ -199,7 +198,7 @@ public final long getSize(String path) throws LuaException {
*/
@LuaFunction
public final boolean exists(String path) {
try {
try (var ignored = environment.time(Metrics.FS_OPS)) {
return getFileSystem().exists(path);
} catch (FileSystemException e) {
return false;
@ -214,7 +213,7 @@ public final boolean exists(String path) {
*/
@LuaFunction
public final boolean isDir(String path) {
try {
try (var ignored = environment.time(Metrics.FS_OPS)) {
return getFileSystem().isDir(path);
} catch (FileSystemException e) {
return false;
@ -229,7 +228,7 @@ public final boolean isDir(String path) {
*/
@LuaFunction
public final boolean isReadOnly(String path) {
try {
try (var ignored = environment.time(Metrics.FS_OPS)) {
return getFileSystem().isReadOnly(path);
} catch (FileSystemException e) {
return false;
@ -244,8 +243,7 @@ public final boolean isReadOnly(String path) {
*/
@LuaFunction
public final void makeDir(String path) throws LuaException {
try {
environment.observe(Metrics.FS_OPS);
try (var ignored = environment.time(Metrics.FS_OPS)) {
getFileSystem().makeDir(path);
} catch (FileSystemException e) {
throw new LuaException(e.getMessage());
@ -263,8 +261,7 @@ public final void makeDir(String path) throws LuaException {
*/
@LuaFunction
public final void move(String path, String dest) throws LuaException {
try {
environment.observe(Metrics.FS_OPS);
try (var ignored = environment.time(Metrics.FS_OPS)) {
getFileSystem().move(path, dest);
} catch (FileSystemException e) {
throw new LuaException(e.getMessage());
@ -282,8 +279,7 @@ public final void move(String path, String dest) throws LuaException {
*/
@LuaFunction
public final void copy(String path, String dest) throws LuaException {
try {
environment.observe(Metrics.FS_OPS);
try (var ignored = environment.time(Metrics.FS_OPS)) {
getFileSystem().copy(path, dest);
} catch (FileSystemException e) {
throw new LuaException(e.getMessage());
@ -301,8 +297,7 @@ public final void copy(String path, String dest) throws LuaException {
*/
@LuaFunction
public final void delete(String path) throws LuaException {
try {
environment.observe(Metrics.FS_OPS);
try (var ignored = environment.time(Metrics.FS_OPS)) {
getFileSystem().delete(path);
} catch (FileSystemException e) {
throw new LuaException(e.getMessage());
@ -365,8 +360,7 @@ public final void delete(String path) throws LuaException {
*/
@LuaFunction
public final Object[] open(String path, String mode) throws LuaException {
environment.observe(Metrics.FS_OPS);
try {
try (var ignored = environment.time(Metrics.FS_OPS)) {
switch (mode) {
case "r" -> {
// Open the file for reading, then create a wrapper around the reader
@ -465,8 +459,7 @@ public final Object getFreeSpace(String path) throws LuaException {
*/
@LuaFunction
public final String[] find(String path) throws LuaException {
try {
environment.observe(Metrics.FS_OPS);
try (var ignored = environment.time(Metrics.FS_OPS)) {
return getFileSystem().find(path);
} catch (FileSystemException e) {
throw new LuaException(e.getMessage());
@ -516,7 +509,7 @@ public final Object getCapacity(String path) throws LuaException {
*/
@LuaFunction
public final Map<String, Object> attributes(String path) throws LuaException {
try {
try (var ignored = environment.time(Metrics.FS_OPS)) {
var attributes = getFileSystem().getAttributes(path);
Map<String, Object> result = new HashMap<>();
result.put("modification", getFileTime(attributes.lastModifiedTime()));

View File

@ -11,7 +11,9 @@
import dan200.computercraft.core.computer.ComputerSide;
import dan200.computercraft.core.computer.GlobalEnvironment;
import dan200.computercraft.core.filesystem.FileSystem;
import dan200.computercraft.core.metrics.OperationTimer;
import dan200.computercraft.core.metrics.Metric;
import dan200.computercraft.core.metrics.MetricsObserver;
import dan200.computercraft.core.terminal.Terminal;
import javax.annotation.Nullable;
@ -68,7 +70,17 @@ interface IPeripheralChangeListener {
void cancelTimer(int id);
void observe(Metric.Event event, long change);
MetricsObserver metrics();
void observe(Metric.Counter counter);
default void observe(Metric.Event event, long change) {
metrics().observe(event, change);
}
default void observe(Metric.Counter counter) {
metrics().observe(counter);
}
default OperationTimer time(Metric.Event event) {
return OperationTimer.start(metrics(), event);
}
}

View File

@ -93,8 +93,9 @@ public MethodResult call(ILuaContext context, String methodName, IArguments argu
if (method == null) throw new LuaException("No such method " + methodName);
environment.observe(Metrics.PERIPHERAL_OPS);
return method.apply(peripheral, context, this, arguments);
try (var ignored = environment.time(Metrics.PERIPHERAL_OPS)) {
return method.apply(peripheral, context, this, arguments);
}
}
// IComputerAccess implementation

View File

@ -10,7 +10,6 @@
import dan200.computercraft.api.peripheral.WorkMonitor;
import dan200.computercraft.core.apis.IAPIEnvironment;
import dan200.computercraft.core.filesystem.FileSystem;
import dan200.computercraft.core.metrics.Metric;
import dan200.computercraft.core.metrics.MetricsObserver;
import dan200.computercraft.core.terminal.Terminal;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
@ -313,13 +312,8 @@ public void cancelTimer(int id) {
}
@Override
public void observe(Metric.Event event, long change) {
metrics.observe(event, change);
}
@Override
public void observe(Metric.Counter counter) {
metrics.observe(counter);
public MetricsObserver metrics() {
return metrics;
}
private static class Timer {

View File

@ -12,11 +12,11 @@ public final class Metrics {
private Metrics() {
}
public static final Metric.Event COMPUTER_TASKS = new Metric.Event("computer_tasks", "ms", Metric::formatTime);
public static final Metric.Event SERVER_TASKS = new Metric.Event("server_tasks", "ms", Metric::formatTime);
public static final Metric.Event COMPUTER_TASKS = new Metric.Event("computer_tasks", "ns", Metric::formatTime);
public static final Metric.Event SERVER_TASKS = new Metric.Event("server_tasks", "ns", Metric::formatTime);
public static final Metric.Counter PERIPHERAL_OPS = new Metric.Counter("peripheral");
public static final Metric.Counter FS_OPS = new Metric.Counter("fs");
public static final Metric.Event PERIPHERAL_OPS = new Metric.Event("peripheral", "ns", Metric::formatTime);
public static final Metric.Event FS_OPS = new Metric.Event("fs", "ns", Metric::formatTime);
public static final Metric.Counter HTTP_REQUESTS = new Metric.Counter("http_requests");
public static final Metric.Event HTTP_UPLOAD = new Metric.Event("http_upload", "bytes", Metric::formatBytes);

View File

@ -0,0 +1,38 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.core.metrics;
/**
* Times how long an operation takes, observing the duration as a {@link Metric.Event}.
*/
public final class OperationTimer implements AutoCloseable {
private final MetricsObserver observer;
private final Metric.Event event;
private final long start;
private OperationTimer(MetricsObserver observer, Metric.Event event, long start) {
this.observer = observer;
this.event = event;
this.start = start;
}
/**
* Start a timer for an operation.
*
* @param observer The metrics observer to submit the operation to.
* @param event The event to observe. The resulting value will be a duration in nanoseconds, and so its
* {@linkplain Metric#unit() unit} should be {@code "ns"}.
* @return The running operation timer.
*/
public static OperationTimer start(MetricsObserver observer, Metric.Event event) {
return new OperationTimer(observer, event, System.nanoTime());
}
@Override
public void close() {
observer.observe(event, System.nanoTime() - start);
}
}

View File

@ -150,7 +150,7 @@ public Stream<DynamicNode> get() throws InterruptedException {
lock.lockInterruptibly();
try {
var remaining = TIMEOUT;
while (remaining > 0 & tests == null) {
while (remaining > 0 && tests == null) {
tick();
if (hasTests.awaitNanos(TICK_TIME) > 0) break;
remaining -= TICK_TIME;

View File

@ -12,7 +12,7 @@
import dan200.computercraft.core.computer.ComputerSide;
import dan200.computercraft.core.computer.GlobalEnvironment;
import dan200.computercraft.core.filesystem.FileSystem;
import dan200.computercraft.core.metrics.Metric;
import dan200.computercraft.core.metrics.MetricsObserver;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.test.core.computer.BasicEnvironment;
@ -123,10 +123,7 @@ public void cancelTimer(int id) {
}
@Override
public void observe(Metric.Event summary, long value) {
}
@Override
public void observe(Metric.Counter counter) {
public MetricsObserver metrics() {
return environment.getMetrics();
}
}