Skip to content

Commit

Permalink
Switch to es6 (#67)
Browse files Browse the repository at this point in the history
* internal/static: js cosmetics

* internal/static: convert to ES6 modules

* _example: ignore dev directory

* _example: minor test log improvements

* internal/static: in ui.js switch to const where possible

* Update CHANGELOG.md
  • Loading branch information
arl authored Feb 20, 2022
1 parent 510e3f1 commit cc1cf3a
Show file tree
Hide file tree
Showing 7 changed files with 547 additions and 605 deletions.
21 changes: 11 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
Unreleased yet
==============
* Build and test all examples
* Polishing (README, small UI improvements)
* Assets are `go:embed`ed, so the minimum go version is now go1.16
* Switch javascript code to ES6 (#65)
* Build and test all examples (#63)
* Assets are `go:embed`ed, so the minimum go version is now go1.16 (#55)
* Polishing (README, small UI improvements) (#54)
* Small ui improvements: link to go.dev rather than golang.org

v0.4.0 / 2021-05-08
==================

* Auto-reconnect to new server from GUI after closed websocket connection (#49)
* Reorganize examples
* Make `IndexAtRoot` returns an `http.HandlerFunc` instead of `http.Handler`
* Reorganize examples (#51)
* Make `IndexAtRoot` returns an `http.HandlerFunc` instead of `http.Handler` (#52)

v0.3.0 / 2021-02-14
==================

* Enable 'save as png' button on plots
* Enable 'save as png' button on plots (#44)

v0.2.2 / 2020-12-13
==================

* Use Go Modules for 'github.com/gorilla/websocket' (#39)
* Support custom frequency (#37)
* Added fixed go-chi example (#38)
* _example: add echo (#22)
* _example: add example gin (#34)
* `_example`: add echo (#22)
* `_example`: add gin example (#34)
* ci: track coverage
* RegisterDefault returns an error now
* Ensure send frequency is a strictly positive integer
* Don't log if we can't upgrade to websocket
* _example: add chi router (#38)
* _example: change structure to have one example per directory
* `_example`_example: add chi router (#38)
* `_example`_example: change structure to have one example per directory
v0.2.1 / 2020-10-29
===================

Expand Down
6 changes: 3 additions & 3 deletions _example/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestExamples(t *testing.T) {
},
}
for _, ent := range ents {
if !ent.IsDir() {
if !ent.IsDir() || ent.Name() == "dev" {
continue
}
t.Run(ent.Name(), func(t *testing.T) {
Expand Down Expand Up @@ -150,12 +150,12 @@ func gorun() (stop func() error, err error) {
if outb.Len() > 0 {
out = outb.String()
}
fmt.Printf("go run, output:\n%s\n", out)
fmt.Printf("command output:\n%s\n", out)
}
}()

if err := <-errc; err != nil {
return nil, fmt.Errorf("go run: %v", err)
return nil, fmt.Errorf("command error: %v", err)
}

return cmd.Process.Kill, nil
Expand Down
105 changes: 53 additions & 52 deletions internal/static/app.js
Original file line number Diff line number Diff line change
@@ -1,66 +1,67 @@
(function() {
function $(id) {
return document.getElementById(id);
}

function buildWebsocketURI() {
var loc = window.location,
ws_prot = "ws:";
if (loc.protocol === "https:") {
ws_prot = "wss:";
}
return ws_prot + "//" + loc.host + loc.pathname + "ws"
}
import * as stats from './stats.js';
import * as ui from './ui.js';

const dataRetentionSeconds = 60;
var timeout = 250;
const $ = id => {
return document.getElementById(id);
}

function clamp(val, min, max) {
if (val < min) return min;
if (val > max) return max;
return val;
const buildWebsocketURI = () => {
var loc = window.location,
ws_prot = "ws:";
if (loc.protocol === "https:") {
ws_prot = "wss:";
}
return ws_prot + "//" + loc.host + loc.pathname + "ws"
}

/* WebSocket connection handling */
const dataRetentionSeconds = 60;
var timeout = 250;

function connect() {
let ws = new WebSocket(buildWebsocketURI());
console.log("Attempting websocket connection to statsviz server...");
const clamp = (val, min, max) => {
if (val < min) return min;
if (val > max) return max;
return val;
}

ws.onopen = () => {
console.log("Successfully connected");
timeout = 250; // reset connection timeout for next time
};
/* WebSocket connection handling */

ws.onclose = event => {
console.log("Closed websocket connection: ", event);
setTimeout(connect, clamp(timeout += timeout, 250, 5000));
};
const connect = () => {
let ws = new WebSocket(buildWebsocketURI());
console.log("Attempting websocket connection to statsviz server...");

ws.onerror = error => {
console.log("Websocket error: ", error);
ws.close();
};
ws.onopen = () => {
console.log("Successfully connected");
timeout = 250; // reset connection timeout for next time
};

var initDone = false;
ws.onmessage = event => {
let allStats = JSON.parse(event.data)
if (!initDone) {
stats.init(dataRetentionSeconds, allStats);
stats.pushData(new Date(), allStats);
initDone = true;
let data = stats.slice(dataRetentionSeconds);
ui.createPlots(data);
return;
}
ws.onclose = event => {
console.log("Closed websocket connection: ", event);
setTimeout(connect, clamp(timeout += timeout, 250, 5000));
};

ws.onerror = error => {
console.log("Websocket error: ", error);
ws.close();
};

var initDone = false;
ws.onmessage = event => {
let allStats = JSON.parse(event.data)
if (!initDone) {
stats.init(dataRetentionSeconds, allStats);
stats.pushData(new Date(), allStats);
if (ui.isPaused()) {
return
}
initDone = true;
let data = stats.slice(dataRetentionSeconds);
ui.updatePlots(data);
ui.createPlots(data);
return;
}

stats.pushData(new Date(), allStats);
if (ui.isPaused()) {
return
}
let data = stats.slice(dataRetentionSeconds);
ui.updatePlots(data);
}
connect();
}());
}
connect();
83 changes: 38 additions & 45 deletions internal/static/buffer.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,46 @@
// Buffer declares the Buffer class.
var Buffer = (function() {
class Buffer {
constructor(len, cap) {
if (cap - len < 0) {
console.Error("cap - len must be positive");
}

// TODO(arl): value using TypedArray rather than Array here
this._buf = new Array(cap);
this._pos = 0;
this._len = len;
this._cap = cap;
export default class Buffer {
constructor(len, cap) {
if (cap - len < 0) {
console.Error("cap - len must be positive");
}
last() {
if (this.length() == 0) {
throw 'Cannot call last() on an empty Buffer';
}
return this._buf[this._pos];
// TODO(arl): value using TypedArray rather than Array here
this._buf = new Array(cap);
this._pos = 0;
this._len = len;
this._cap = cap;
}
last() {
if (this.length() == 0) {
throw 'Cannot call last() on an empty Buffer';
}
push(pt) {
if (this._pos >= this._cap) {
// move data to the beggining of the buffer, effectively discarding
// the cap-len oldest elements
this._buf.copyWithin(0, this._cap - this._len);
this._pos = this._len;
}

this._buf[this._pos] = pt;
this._pos++;
return this._buf[this._pos];
}
push(pt) {
if (this._pos >= this._cap) {
// move data to the beggining of the buffer, effectively discarding
// the cap-len oldest elements
this._buf.copyWithin(0, this._cap - this._len);
this._pos = this._len;
}
length() {
if (this._pos > this._len) {
return this._len;
}

return this._pos;
}
// slice returns a slice of the len latest datapoints present in the buffer.
slice(len) {
// Cap the dimension of the returned slice to the data available
if (len > this.length()) {
len = this.length();
}

let start = this._pos - len;
return this._buf.slice(start, start + len);
this._buf[this._pos] = pt;
this._pos++;
}
length() {
if (this._pos > this._len) {
return this._len;
}
return this._pos;
}

// slice returns a slice of the len latest datapoints present in the buffer.
slice(len) {
// Cap the dimension of the returned slice to the data available
if (len > this.length()) {
len = this.length();
}

return Buffer;
}());
let start = this._pos - len;
return this._buf.slice(start, start + len);
}
};
24 changes: 7 additions & 17 deletions internal/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,19 @@

<div class="ui styled fluid accordion">
<div class="active title">
<i class="dropdown icon"></i>
Heap
<i class="dropdown icon"></i> Heap
</div>
<div class="active content">
<div id="heap" class="transition visible plot"></div>
</div>
<div class="title">
<i class="dropdown icon"></i>
MSpan / MCache
<i class="dropdown icon"></i> MSpan / MCache
</div>
<div class="content">
<div id="mspan-mcache" class="transition hidden plot"></div>
</div>
<div class="title">
<i class="dropdown icon"></i>
Size Classes
<i class="dropdown icon"></i> Size Classes
</div>
<div class="content">
<div id="size-classes" class="transition hidden plot"></div>
Expand All @@ -59,34 +56,27 @@
<div class="eight wide column reveal" style="flex: 0 0 800px;">
<div class="ui styled fluid accordion">
<div class="title">
<i class="dropdown icon"></i>
Objects
<i class="dropdown icon"></i> Objects
</div>
<div class="content">
<div id="objects" class="transition visible plot"></div>
</div>
<div class="title">
<i class="dropdown icon"></i>
Goroutines
<i class="dropdown icon"></i> Goroutines
</div>
<div class="content">
<div id="goroutines" class="transition visible plot"></div>
</div>
<div class="title">
<i class="dropdown icon"></i>
GC / CPU fraction
<i class="dropdown icon"></i> GC / CPU fraction
</div>
<div class="content">
<div id="gcfraction" class="transition hidden plot"></div>
</div>
</div>
</div>


<script src="./buffer.js"></script>
<script src="./stats.js"></script>
<script src="./ui.js"></script>
<script src="./app.js"></script>
<script type="module" src="./app.js"></script>
</body>

</html>
Loading

0 comments on commit cc1cf3a

Please sign in to comment.