Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 54 additions & 16 deletions rust/meta/src/dashboard/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,18 @@ <h1 class="mb-2 text-sm leading-6 font-semibold text-sky-500 dark:text-sky-400">
<div id="clusters" class="grid gap-2 md:grid-cols-2 lg:grid-cols-3 w-full">
</div>

<h1 class="mt-5 mb-2 text-sm leading-6 font-semibold text-sky-500 dark:text-sky-400">
Stream Actors
</h1>
<div class="flex mt-5 mb-2 text-sm">
<h1 class="flex-auto leading-6 font-semibold text-sky-500 dark:text-sky-400">
Stream Actors
</h1>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="mvOnMvCheckbox"
onchange="handleMvOnMvClick(this);">
<label class="form-check-label text-gray-500" for="mvOnMvCheckbox">
Resolve MV on MV
</label>
</div>
</div>
<div id="actors" class="w-full">
</div>
</div>
Expand All @@ -75,6 +84,9 @@ <h1 class="mt-5 mb-2 text-sm leading-6 font-semibold text-sky-500 dark:text-sky-
integrity="sha256-ZjkehPx5n2M0daimR+hR4q8q4wIcPUNUrUTsykjK56Y=" crossorigin="anonymous"></script>

<script>
/// Whether we should resolve mv on mv
let resolveMvOnMv = false

const cluster = (type, cluster) => `
<div class="p-6 max-w bg-white rounded-xl shadow-md flex flex-col space-y-1">
<div class="flex flex-row items-center">
Expand Down Expand Up @@ -239,7 +251,7 @@ <h1 class="mt-5 mb-2 text-sm leading-6 font-semibold text-sky-500 dark:text-sky-

/// Create a d3.hierarchy of actors
const hierarchyActors = (actors, metaFn) => {
/// Mapping fragmentId -> { [actorId], parent }
/// Mapping fragmentId -> { [actorId], [parent] }
const actorNodes = new Map
/// actorId -> Actor
const actorMap = new Map
Expand All @@ -260,18 +272,34 @@ <h1 class="mt-5 mb-2 text-sm leading-6 font-semibold text-sky-500 dark:text-sky-
}
lastFragmentId = downstreamFragmentId
})
actorNodes.set(fragmentId, { actors: [actorId], parent: lastFragmentId })
const parents = lastFragmentId ? [lastFragmentId] : []
actorNodes.set(fragmentId, { actors: [actorId], parents })
} else {
actorNodes.get(fragmentId).actors.push(actorId)
}
})

/// Resolve MV on MV
if (resolveMvOnMv) {
actors.forEach(actor => {
const fragmentId = fragmentIdOf(actor)

if (actor.nodes.chainNode) {
let upstreamActorIds = actor.nodes.chainNode.upstreamActorIds
if (upstreamActorIds.length != 0) {
let upstreamFragmentId = fragmentIdOf(actorMap.get(upstreamActorIds[0]))
actorNodes.get(upstreamFragmentId).parents.push(fragmentId)
}
}
})
}

/// Reverse mapping
const actorReverseMapping = new Map

/// Get reverse mapping
actorNodes.forEach(({ actors, parent }, fragmentId) => {
if (parent) {
actorNodes.forEach(({ actors, parents }, fragmentId) => {
for (const parent of parents) {
const list = (actorReverseMapping.get(parent) || [])
list.push(fragmentId)
actorReverseMapping.set(parent, list)
Expand All @@ -281,7 +309,7 @@ <h1 class="mt-5 mb-2 text-sm leading-6 font-semibold text-sky-500 dark:text-sky-
const roots = []

/// Split into multiple graphs
actorNodes.forEach(({ actors, parent }, fragmentId) => {
actorNodes.forEach(({ actors, parents }, fragmentId) => {
const buildGraph = (root, nextColor) => (
{
id: root,
Expand All @@ -292,7 +320,7 @@ <h1 class="mt-5 mb-2 text-sm leading-6 font-semibold text-sky-500 dark:text-sky-

const countGraph = (root) => _.sum((actorReverseMapping.get(root) || []).map(countGraph)) + 1

if (!parent) {
if (parents.length == 0) {
const totalActors = countGraph(fragmentId)
let countedActor = 0
const interp = d3.interpolateRainbow
Expand Down Expand Up @@ -465,13 +493,23 @@ <h1 class="mt-5 mb-2 text-sm leading-6 font-semibold text-sky-500 dark:text-sky-
data => $("#clusters").append(cluster("Compute Node", data))))
$("#clusters").append(cluster("Meta Node", { host: { host: "127.0.0.1", port: "2333" } }))

fetch('/api/actors')
.then(response => response.json())
.then(data => data.forEach(
(data, operatorId) => {
$("#actors").append(actors(data, operatorId))
layoutStreamGraphs(data, operatorId)
}))
const loadActors = () => {
fetch('/api/actors')
.then(response => response.json())
.then(data => data.forEach(
(data, operatorId) => {
$("#actors").empty()
$("#actors").append(actors(data, operatorId))
layoutStreamGraphs(data, operatorId)
}))
}

const handleMvOnMvClick = (cb) => {
resolveMvOnMv = cb.checked
loadActors()
}

loadActors()

</script>

Expand Down