Request metrics again via state
This commit is contained in:
parent
f77ed130e1
commit
c9ff8ab228
3 changed files with 106 additions and 31 deletions
|
|
@ -1,3 +1,6 @@
|
||||||
|
import { Metrics } from "./graph/metrics.js";
|
||||||
|
import { State } from "./graph/state.js";
|
||||||
|
|
||||||
import uPlot from "./uPlot.js";
|
import uPlot from "./uPlot.js";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -120,4 +123,10 @@ const COLORS = [
|
||||||
|
|
||||||
const plotDiv = document.getElementById("plot")!;
|
const plotDiv = document.getElementById("plot")!;
|
||||||
const metricsDiv = document.getElementById("metrics")!;
|
const metricsDiv = document.getElementById("metrics")!;
|
||||||
let plot: uPlot | null = null;
|
|
||||||
|
const metrics = new Metrics(metricsDiv);
|
||||||
|
const state = new State(metrics);
|
||||||
|
state.update();
|
||||||
|
|
||||||
|
// For debugging
|
||||||
|
(window as any).state = state;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { MetricsResponse } from "./requests.js";
|
||||||
import { el } from "./util.js";
|
import { el } from "./util.js";
|
||||||
|
|
||||||
class Folder {
|
class Folder {
|
||||||
|
|
@ -57,12 +58,50 @@ class Folder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateMetricsDiv(div: HTMLElement, metrics: string[]) {
|
export class Metrics {
|
||||||
let folder = new Folder();
|
#div: HTMLElement;
|
||||||
for (let metric of metrics) {
|
#dataId: number | null = null;
|
||||||
folder.add(metric);
|
|
||||||
|
constructor(div: HTMLElement) {
|
||||||
|
this.#div = div;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.textContent = ""; // Remove children
|
getSelected(): Set<string> {
|
||||||
div.append(folder.childrenToHtmlElements());
|
const selected = new Set<string>();
|
||||||
|
|
||||||
|
const checkedInputs = this.#div.querySelectorAll<HTMLInputElement>("input:checked");
|
||||||
|
for (const input of checkedInputs) {
|
||||||
|
selected.add(input.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
requiresUpdate(dataId: number): boolean {
|
||||||
|
// At the moment, updating the metrics results in all <details> tags
|
||||||
|
// closing again. To prevent this (as it can be frustrating if you've
|
||||||
|
// navigated deep into the metrics hierarchy), we never require updates
|
||||||
|
// after the initial update.
|
||||||
|
return this.#dataId === null;
|
||||||
|
// return this.#dataId === null || this.#dataId < dataId;
|
||||||
|
}
|
||||||
|
|
||||||
|
update(response: MetricsResponse) {
|
||||||
|
const selected = this.getSelected();
|
||||||
|
|
||||||
|
const folder = new Folder();
|
||||||
|
for (const metric of response.metrics) {
|
||||||
|
folder.add(metric);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#div.textContent = ""; // Remove children
|
||||||
|
this.#div.append(folder.childrenToHtmlElements());
|
||||||
|
|
||||||
|
const inputs = this.#div.querySelectorAll<HTMLInputElement>("input");
|
||||||
|
for (const input of inputs) {
|
||||||
|
input.checked = selected.has(input.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#dataId = response.dataId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,67 @@
|
||||||
import { updateMetricsDiv } from "./metrics.js";
|
import { Metrics } from "./metrics.js";
|
||||||
import { MetricsResponse, getMetrics } from "./requests.js";
|
import { getMetrics } from "./requests.js";
|
||||||
|
|
||||||
export class State {
|
export class State {
|
||||||
#metricsDiv: HTMLElement;
|
#latestGraphId: number = -Infinity;
|
||||||
|
#latestDataId: number = -Infinity;
|
||||||
|
|
||||||
#updating: boolean = false;
|
#metrics: Metrics;
|
||||||
#metrics: MetricsResponse | null = null;
|
|
||||||
|
|
||||||
constructor(metricsDiv: HTMLElement) {
|
#requestingNewMetrics: boolean = false;
|
||||||
this.#metricsDiv = metricsDiv;
|
|
||||||
|
// commits (with graph id and data id)
|
||||||
|
// raw measurements (with graph id and data id)
|
||||||
|
// processed measurements (with graph id and data id)
|
||||||
|
|
||||||
|
constructor(metrics: Metrics) {
|
||||||
|
this.#metrics = metrics;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look at current state and try to change it so that it represents what the
|
* Update state and plot and request new data if necessary. Tries to match
|
||||||
* user wants.
|
* the user's wishes as closely as possible.
|
||||||
*
|
*
|
||||||
* This function is idempotent.
|
* This function is idempotent.
|
||||||
*/
|
*/
|
||||||
async update() {
|
update() {
|
||||||
if (this.#updating) {
|
// TODO Invalidate and update data
|
||||||
return;
|
// TODO Update graph
|
||||||
|
this.#requestDataWhereNecessary();
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// Requesting and updating data //
|
||||||
|
//////////////////////////////////
|
||||||
|
|
||||||
|
#updateDataId(dataId: number) {
|
||||||
|
if (dataId > this.#latestDataId) {
|
||||||
|
this.#latestDataId = dataId;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#updateGraphId(graphId: number) {
|
||||||
|
if (graphId > this.#latestGraphId) {
|
||||||
|
this.#latestGraphId = graphId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#requestDataWhereNecessary() {
|
||||||
|
if (this.#metrics.requiresUpdate(this.#latestDataId)) {
|
||||||
|
this.#requestMetrics();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async #requestMetrics() {
|
||||||
|
if (this.#requestingNewMetrics) return;
|
||||||
|
console.log("Requesting new metrics");
|
||||||
try {
|
try {
|
||||||
await this.#update_impl();
|
this.#requestingNewMetrics = true;
|
||||||
|
const response = await getMetrics();
|
||||||
|
this.#updateDataId(response.dataId);
|
||||||
|
this.#metrics.update(response);
|
||||||
|
this.update();
|
||||||
} finally {
|
} finally {
|
||||||
this.#updating = false;
|
this.#requestingNewMetrics = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async #update_impl() {
|
|
||||||
this.#update_metrics();
|
|
||||||
}
|
|
||||||
|
|
||||||
async #update_metrics() {
|
|
||||||
this.#metrics = await getMetrics();
|
|
||||||
if (this.#metrics === null) { return; }
|
|
||||||
updateMetricsDiv(this.#metricsDiv, this.#metrics.metrics);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue