Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
tomtzook committed Jan 15, 2024
2 parents 21f1448 + f0a0e0d commit 35c64bd
Show file tree
Hide file tree
Showing 17 changed files with 633 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,26 @@
import com.flash3388.flashlib.app.net.NetworkConfiguration;
import com.flash3388.flashlib.app.net.NetworkInterface;
import com.flash3388.flashlib.app.net.NetworkInterfaceImpl;
import com.flash3388.flashlib.app.watchdog.FeedReporter;
import com.flash3388.flashlib.app.watchdog.InternalWatchdog;
import com.flash3388.flashlib.app.watchdog.LoggingFeedReporter;
import com.flash3388.flashlib.app.watchdog.MultiFeedReporters;
import com.flash3388.flashlib.app.watchdog.Watchdog;
import com.flash3388.flashlib.app.watchdog.WatchdogImpl;
import com.flash3388.flashlib.app.watchdog.WatchdogService;
import com.flash3388.flashlib.net.obsr.ObjectStorage;
import com.flash3388.flashlib.net.obsr.StoredObject;
import com.flash3388.flashlib.time.Clock;
import com.flash3388.flashlib.time.SystemNanoClock;
import com.flash3388.flashlib.time.Time;
import com.flash3388.flashlib.util.FlashLibMainThread;
import com.flash3388.flashlib.util.FlashLibMainThreadImpl;
import com.flash3388.flashlib.util.logging.Logging;
import com.flash3388.flashlib.util.resources.ResourceHolder;
import com.flash3388.flashlib.util.unique.InstanceId;
import org.slf4j.Logger;

import java.util.Arrays;
import java.util.Collection;

public class BasicFlashLibControl implements FlashLibControl {
Expand All @@ -25,6 +36,7 @@ public class BasicFlashLibControl implements FlashLibControl {
private final ServiceRegistry mServiceRegistry;
private final NetworkInterface mNetworkInterface;
private final FlashLibMainThread mMainThread;
private final WatchdogService mWatchdogService;

public BasicFlashLibControl(InstanceId instanceId,
ResourceHolder resourceHolder,
Expand All @@ -37,6 +49,9 @@ public BasicFlashLibControl(InstanceId instanceId,
mServiceRegistry = new BasicServiceRegistry(mMainThread);
mNetworkInterface = new NetworkInterfaceImpl(
networkConfiguration, instanceId, mServiceRegistry, mClock, mMainThread);
mWatchdogService = new WatchdogService();

mServiceRegistry.register(mWatchdogService);
}

public BasicFlashLibControl(InstanceId instanceId, ResourceHolder resourceHolder) {
Expand Down Expand Up @@ -78,4 +93,23 @@ public NetworkInterface getNetworkInterface() {
public FlashLibMainThread getMainThread() {
return mMainThread;
}

@Override
public Watchdog newWatchdog(String name, Time timeout, FeedReporter reporter) {
StoredObject rootObject = WatchdogImpl.getWatchdogStoredObject(this, name);
FeedReporter feedReporter = new MultiFeedReporters(Arrays.asList(new LoggingFeedReporter(), reporter));
InternalWatchdog watchdog = new WatchdogImpl(getClock(), name, timeout, feedReporter, rootObject);
mWatchdogService.register(watchdog);

return watchdog;
}

@Override
public Watchdog newWatchdog(String name, Time timeout) {
StoredObject rootObject = WatchdogImpl.getWatchdogStoredObject(this, name);
InternalWatchdog watchdog = new WatchdogImpl(getClock(), name, timeout, new LoggingFeedReporter(), rootObject);
mWatchdogService.register(watchdog);

return watchdog;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.flash3388.flashlib.app;

import com.flash3388.flashlib.app.net.NetworkInterface;
import com.flash3388.flashlib.app.watchdog.FeedReporter;
import com.flash3388.flashlib.app.watchdog.Watchdog;
import com.flash3388.flashlib.time.Clock;
import com.flash3388.flashlib.time.Time;
import com.flash3388.flashlib.util.FlashLibMainThread;
import com.flash3388.flashlib.util.unique.InstanceId;
import org.slf4j.Logger;
Expand Down Expand Up @@ -50,4 +53,14 @@ public NetworkInterface getNetworkInterface() {
public FlashLibMainThread getMainThread() {
return mControl.getMainThread();
}

@Override
public Watchdog newWatchdog(String name, Time timeout, FeedReporter reporter) {
return mControl.newWatchdog(name, timeout, reporter);
}

@Override
public Watchdog newWatchdog(String name, Time timeout) {
return mControl.newWatchdog(name, timeout);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import com.flash3388.flashlib.annotations.MainThreadOnly;
import com.flash3388.flashlib.app.net.NetworkInterface;
import com.flash3388.flashlib.app.net.NetworkingMode;
import com.flash3388.flashlib.app.watchdog.FeedReporter;
import com.flash3388.flashlib.app.watchdog.Watchdog;
import com.flash3388.flashlib.time.Clock;
import com.flash3388.flashlib.time.Time;
import com.flash3388.flashlib.util.FlashLibMainThread;
import com.flash3388.flashlib.util.unique.InstanceId;
import org.slf4j.Logger;
Expand Down Expand Up @@ -114,4 +117,44 @@ default void registerCloseables(AutoCloseable... closeables) {
*/
FlashLibMainThread getMainThread();

/**
* Creates a new watchdog, used to track run of services, threads or loops. As a way to ensure
* it runs within a specific time.
*
* To use the watchdog, the target must periodically call {@link Watchdog#feed()}. As long as
* it keeps updating the {@link Watchdog} in time, then we can assume that it is up and running.
* If the target does not update the watchdog within a set amount of time, then it is considered <em>expired</em>
* while will be reported.
*
* The watchdog must first be enabled for usage with {@link Watchdog#enable()}.
*
* @param name name of the watchdog
* @param timeout time within the watchdog is expected to be updated, if the watchdog was not updated within
* the given time, it is <em>expired</em> and this will be reported.
* @param reporter reporter to updated on <em>expiration</em>
* @return {@link Watchdog}
*
* @see #newWatchdog(String, Time)
*/
Watchdog newWatchdog(String name, Time timeout, FeedReporter reporter);

/**
* Creates a new watchdog, used to track run of services, threads or loops. As a way to ensure
* it runs within a specific time.
*
* To use the watchdog, the target must periodically call {@link Watchdog#feed()}. As long as
* it keeps updating the {@link Watchdog} in time, then we can assume that it is up and running.
* If the target does not update the watchdog within a set amount of time, then it is considered <em>expired</em>
* while will be reported to the log.
*
* The watchdog must first be enabled for usage with {@link Watchdog#enable()}.
*
* @param name name of the watchdog
* @param timeout time within the watchdog is expected to be updated, if the watchdog was not updated within
* the given time, it is <em>expired</em> and this will be reported.
* @return {@link Watchdog}
*
* @see #newWatchdog(String, Time, FeedReporter)
*/
Watchdog newWatchdog(String name, Time timeout);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.flash3388.flashlib.app.watchdog;

import com.flash3388.flashlib.time.Time;

import java.util.List;

public interface FeedReporter {

void reportFeed(String watchdogName);
void reportFeedExpired(String watchdogName, Time feedOverrun, List<TimestampReport> reports);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.flash3388.flashlib.app.watchdog;

import com.flash3388.flashlib.time.Time;

public interface InternalWatchdog extends Watchdog {

Time getTimeLeftToTimeout();

void checkFed();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.flash3388.flashlib.app.watchdog;

import com.flash3388.flashlib.time.Time;
import com.flash3388.flashlib.util.logging.Logging;
import org.slf4j.Logger;

import java.util.List;

public class LoggingFeedReporter implements FeedReporter {

private static final Logger LOGGER = Logging.getLogger("Watchdog");

@Override
public void reportFeed(String watchdogName) {
// do not report
}

@Override
public void reportFeedExpired(String watchdogName, Time feedOverrun, List<TimestampReport> reports) {
StringBuilder builder = new StringBuilder();

builder.append("Watchdog ").append(watchdogName).append(" overrun report\n");
builder.append("Time overrun:\t").append(String.format("%.3fs\n", feedOverrun.valueAsSeconds()));
builder.append("Timestamps:\n");

for (TimestampReport report : reports) {
builder.append('\t').append(report.getKey()).append(":")
.append(String.format("%.3fs\n", report.getReportTime().valueAsSeconds()));
}

LOGGER.warn(builder.toString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.flash3388.flashlib.app.watchdog;

import com.flash3388.flashlib.time.Time;

import java.util.Collection;
import java.util.List;

public class MultiFeedReporters implements FeedReporter {

private final Collection<FeedReporter> mReporters;

public MultiFeedReporters(Collection<FeedReporter> reporters) {
mReporters = reporters;
}

@Override
public void reportFeed(String watchdogName) {
for (FeedReporter reporter : mReporters) {
reporter.reportFeed(watchdogName);
}
}

@Override
public void reportFeedExpired(String watchdogName, Time feedOverrun, List<TimestampReport> reports) {
for (FeedReporter reporter : mReporters) {
reporter.reportFeedExpired(watchdogName, feedOverrun, reports);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.flash3388.flashlib.app.watchdog;

import com.flash3388.flashlib.time.Time;

public class TimestampReport {

private final String mKey;
private final Time mReportTime;

public TimestampReport(String key, Time reportTime) {
mKey = key;
mReportTime = reportTime;
}

public String getKey() {
return mKey;
}

public Time getReportTime() {
return mReportTime;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.flash3388.flashlib.app.watchdog;

import com.flash3388.flashlib.time.Time;

public interface Watchdog {

/**
* Gets the name of the watchdog.
*
* @return name, representative of the watchdog.
*/
String getName();

/**
* Gets the feed timeout of the watchdog.
*
* @return time
*/
Time getTimeout();

/**
* Gets whether the watchdog is currently enabled.
*
* @return <b>true</b> if enabled, <b>false</b> otherwise.
*/
boolean isEnabled();

/**
* Gets whether the feeding timer has expired. Measured according to the last
* call to {@link #feed()}.
*
* @return <b>true</b> if expired, <b>false</b> otherwise.
*/
boolean isExpired();

/**
* Disables the feeding check of the watchdog.
* Should be used when the target for the watchdog is not running or executing a
* segment which should not be measured.
*/
void disable();

/**
* Enables the feeding check of the watchdog. Effectively restarting
* each functionality.
*/
void enable();

/**
* Register a timestamp report. Use this to report on the progress of the target
* for help debugging which parts of the target cause delays in execution.
*
* @param key storage key identifier, should be unique for this timestamp.
*/
void reportTimestamp(String key);

/**
* Feeds the watchdog, updating it that the target is still functioning. Should
* be called periodically at specific location to indicate that the target is still
* functioning.
*/
void feed();
}
Loading

0 comments on commit 35c64bd

Please sign in to comment.