Skip to content

Commit

Permalink
return stats from the compute server, total them in the client
Browse files Browse the repository at this point in the history
Nothing is displayed yet.
  • Loading branch information
nedbat committed Aug 1, 2021
1 parent 7b9aaaf commit 1be0be9
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 11 deletions.
29 changes: 22 additions & 7 deletions src/aptus/web/server.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ast
import asyncio
import base64
import dataclasses
import functools
import io
import os
Expand Down Expand Up @@ -43,24 +44,37 @@ def inner(*args, **kwargs):
return loop.run_in_executor(None, lambda: f(*args, **kwargs))
return inner


@dataclasses.dataclass
class CachedResult:
counts: object # ndarray
stats: dict

@dataclasses.dataclass
class TileResult:
pixels: bytes
stats: dict


# Cache of computed counts. One tile is about 830Kb.
cache_size = int(os.getenv("APTUS_CACHE", "500"))
tile_cache = cachetools.LRUCache(cache_size * 1_000_000, getsizeof=lambda nda: nda.nbytes)
tile_cache = cachetools.LRUCache(cache_size * 1_000_000, getsizeof=lambda cr: cr.counts.nbytes)

@run_in_executor
def compute_tile(compute, cachekey):
old = tile_cache.get(cachekey)
if old is None:
compute.compute_array()
stats = compute.stats
tile_cache[cachekey] = CachedResult(counts=compute.counts, stats=stats)
else:
compute.set_counts(old)
if old is None:
tile_cache[cachekey] = compute.counts
compute.set_counts(old.counts)
stats = old.stats
pix = compute.color_mandel()
im = PIL.Image.fromarray(pix)
fout = io.BytesIO()
compute.write_image(im, fout)
return fout.getvalue()
return TileResult(pixels=fout.getvalue(), stats=stats)

@run_in_executor
def compute_render(compute):
Expand Down Expand Up @@ -126,11 +140,12 @@ async def tile(req: TileRequest):
{spec.iter_limit}
{spec.coords}
"""
data = await compute_tile(compute, cachekey)
data_url = "data:image/png;base64," + base64.b64encode(data).decode("ascii")
results = await compute_tile(compute, cachekey)
data_url = "data:image/png;base64," + base64.b64encode(results.pixels).decode("ascii")
return {
"url": data_url,
"seq": req.seq,
"stats": results.stats,
}

@app.post("/render")
Expand Down
44 changes: 40 additions & 4 deletions src/aptus/web/static/aptus.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ const View = {
}
this.tiles_pending = imageurls.length;
this.overlay_canvas.classList.add("wait");
this.stats = Object.create(Stats);
return Promise.all(imageurls.map(getImage));
},

Expand Down Expand Up @@ -212,6 +213,10 @@ const View = {
},
};

function getImage(tile) {
return fetchTile(tile).then(showTile);
}

function fetchTile(tile) {
return new Promise(resolve => {
const body = {
Expand All @@ -222,6 +227,7 @@ function fetchTile(tile) {
.then(response => response.json())
.then(tiledata => {
if (tiledata.seq == tile.view.reqseq) {
tile.view.stats.add(tiledata.stats);
tile.img = new Image();
tile.img.src = tiledata.url;
tile.img.onload = () => resolve(tile);
Expand All @@ -239,10 +245,6 @@ function showTile(tile) {
}
}

function getImage(tile) {
return fetchTile(tile).then(showTile);
}

function fetch_post_json(url, body) {
return fetch(url, {
method: "POST",
Expand All @@ -264,6 +266,40 @@ function fetch_post_json(url, body) {
});
}

const Stats = {
boundaries: 0,
boundariesfilled: 0,
computedpoints: 0,
filledpoints: 0,
largestfilled: 0,
longestboundary: 0,
maxedpoints: 0,
maxiter: 0,
maxitercycle: 0,
miniter: 0,
minitercycle: 0,
miniteredge: 0,
totalcycles: 0,
totaliter: 0,

add(more) {
this.boundaries += more.boundaries;
this.boundariesfilled += more.boundariesfilled;
this.computedpoints += more.computedpoints;
this.filledpoints += more.filledpoints;
this.largestfilled = Math.max(this.largestfilled, more.largestfilled);
this.longestboundary = Math.max(this.longestboundary, more.longestboundary);
this.maxedpoints += more.maxedpoints;
this.maxiter = Math.max(this.maxiter, more.maxiter);
this.maxitercycle = Math.max(this.maxitercycle, more.maxitercycle);
this.miniter = (this.miniter == 0) ? more.miniter : Math.min(this.miniter, more.miniter);
this.minitercycle = (this.minitercycle == 0) ? more.minitercycle : Math.min(this.minitercycle, more.minitercycle);
this.miniteredge = (this.miniteredge == 0) ? more.miniteredge : Math.min(this.miniteredge, more.miniteredge);
this.totalcycles += more.totalcycles;
this.totaliter += more.totaliter;
},
}

const App = {
main() {
if (platform() === "mac") {
Expand Down

0 comments on commit 1be0be9

Please sign in to comment.