Skip to content

Commit

Permalink
implement database persistence for trace routes
Browse files Browse the repository at this point in the history
  • Loading branch information
liamcottle committed Nov 18, 2024
1 parent 2f2134f commit dc33f5e
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 67 deletions.
2 changes: 1 addition & 1 deletion src/components/messages/MessageViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export default {
onMessagesUpdated(messages) {
// update messages in ui
this.messages = messages;
this.messages = messages.map((message) => message.toJSON());
// auto scroll to bottom if we want to
if(this.autoScrollOnNewMessage){
Expand Down
21 changes: 15 additions & 6 deletions src/components/pages/NodeRunTraceRoutePage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import Page from "./Page.vue";
import NodeUtils from "../../js/NodeUtils.js";
import NodeAPI from "../../js/NodeAPI.js";
import Connection from "../../js/Connection.js";
import Database from "../../js/Database.js";
export default {
name: 'NodeTracesRoutePage',
Expand Down Expand Up @@ -115,9 +116,6 @@ export default {
},
methods: {
getNodeLongName: (nodeId) => NodeUtils.getNodeLongName(nodeId),
onNewTraceRouteClick(node) {
NodeAPI.traceRoute(node.num);
},
async runTraceRoute(node) {
// do nothing if already running
Expand All @@ -129,7 +127,11 @@ export default {
this.isRunningTraceRoute = true;
// run trace route
await NodeAPI.traceRoute(node.num);
try {
await NodeAPI.traceRoute(node.num);
} catch(e) {
// don't care about timeout
}
},
onIgnoreResultClick() {
Expand All @@ -142,18 +144,25 @@ export default {
}
}
},
onTraceRouteComplete(traceRoute) {
async onTraceRouteComplete(traceRoute) {
// no longer running trace route
this.isRunningTraceRoute = false;
// find latest trace route by packet id
const databaseTraceRoute = await Database.TraceRoute.findTraceRouteByPacketId(traceRoute.id).exec();
if(!databaseTraceRoute){
return;
}
// go to trace route page
this.$router.push({
name: "traceroute",
params: {
traceRouteId: traceRoute.id,
traceRouteId: databaseTraceRoute.id,
},
});
},
onClientNotification(clientNotification) {
Expand Down
64 changes: 30 additions & 34 deletions src/components/pages/NodeTraceRoutesPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,24 @@
</AppBar>

<!-- list -->
<div class="h-full w-full overflow-hidden">
<div v-for="traceRoute of reversedTraceRoutes" class="w-full">
<RouterLink :to="{ name: 'traceroute', params: { traceRouteId: traceRoute.id} }">
<div class="flex p-2 bg-white hover:bg-gray-50">
<div>
<div class="text-sm text-gray-900">
<span class="font-medium">{{ getNodeLongName(traceRoute.to) || '???' }}</span>
<span> to </span>
<span class="font-medium">{{ getNodeLongName(traceRoute.from) || '???' }}</span>
</div>
<div class="text-sm text-gray-700">
{{ getTimeAgo(traceRoute.rxTime) }} • {{ traceRoute.data.route.length }} hop(s) on channel {{ getChannelName(traceRoute.channel) }}
<div class="flex h-full w-full overflow-hidden">
<div class="w-full overflow-y-auto">
<div v-for="traceRoute of traceRoutes">
<RouterLink :to="{ name: 'traceroute', params: { traceRouteId: traceRoute.id} }">
<div class="flex p-2 bg-white hover:bg-gray-50">
<div>
<div class="text-sm text-gray-900">
<span class="font-medium">{{ getNodeLongName(traceRoute.to) || '???' }}</span>
<span> to </span>
<span class="font-medium">{{ getNodeLongName(traceRoute.from) || '???' }}</span>
</div>
<div class="text-sm text-gray-700">
{{ getTimeAgo(new Date(traceRoute.timestamp)) }} • {{ traceRoute.data.route.length }} hop(s) on channel {{ getChannelName(traceRoute.channel) }}
</div>
</div>
</div>
</div>
</RouterLink>
</RouterLink>
</div>
</div>
</div>

Expand All @@ -47,9 +49,9 @@ import NodeIcon from "../nodes/NodeIcon.vue";
import Page from "./Page.vue";
import NodeUtils from "../../js/NodeUtils.js";
import IconButton from "../IconButton.vue";
import NodeAPI from "../../js/NodeAPI.js";
import ChannelUtils from "../../js/ChannelUtils.js";
import TimeUtils from "../../js/TimeUtils.js";
import Database from "../../js/Database.js";
export default {
name: 'NodeTracesRoutePage',
Expand All @@ -62,23 +64,26 @@ export default {
props: {
nodeId: String | Number,
},
data() {
return {
traceRoutes: [],
traceRoutesSubscription: null,
};
},
mounted() {
// redirect to main page if node not found
if(!this.node){
this.$router.push({
name: "main",
});
return;
}
// init database subscription for trace routes
this.traceRoutesSubscription = Database.TraceRoute.getTraceRoutesByNodeId(this.nodeId).$.subscribe((traceRoutes) => {
this.traceRoutes = traceRoutes.map((traceRoute) => traceRoute.toJSON()).reverse();
});
},
unmounted() {
this.traceRoutesSubscription?.unsubscribe();
},
methods: {
getNodeLongName: (nodeId) => NodeUtils.getNodeLongName(nodeId),
getTimeAgo: (date) => TimeUtils.getTimeAgo(date),
onNewTraceRouteClick(node) {
NodeAPI.traceRoute(node.num);
},
getChannelName: (channelId) => {
return ChannelUtils.getChannelName(channelId) || `#${channelId}`;
},
Expand All @@ -90,15 +95,6 @@ export default {
subtitle() {
return this.node ? this.getNodeLongName(this.node.num) : "Unknown Node";
},
traceRoutes() {
// return traceroute responses from this node to us
return Object.values(GlobalState.traceRoutesById).filter((traceRoute) => {
return traceRoute.from === this.node.num && traceRoute.to === GlobalState.myNodeId;
});
},
reversedTraceRoutes() {
return this.traceRoutes.reverse();
},
},
}
</script>
42 changes: 23 additions & 19 deletions src/components/pages/TraceRoutePage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@
</div>
<div class="my-auto relative flex flex-none items-center justify-center">
<div>
<NodeIcon :node="findNodeById(this.traceRoute.to)"/>
<NodeIcon :node="findNodeById(traceRoute.to)"/>
</div>
</div>
<div class="flex-auto py-0.5 text-sm leading-5 text-gray-500">
<div class="font-medium text-gray-900">{{ getNodeLongName(this.traceRoute.to) || '???' }}</div>
<div>{{ getNodeHexId(this.traceRoute.to) }}</div>
<div class="font-medium text-gray-900">{{ getNodeLongName(traceRoute.to) || '???' }}</div>
<div>{{ getNodeHexId(traceRoute.to) }}</div>
<div>Started the traceroute</div>
</div>
</li>

<!-- middleman nodes -->
<li v-for="route of this.traceRoute.data.route" class="relative flex gap-x-4">
<li v-for="route of traceRoute.data.route" class="relative flex gap-x-4">
<div class="absolute left-0 top-0 flex w-12 justify-center -bottom-3">
<div class="w-px bg-gray-200"></div>
</div>
Expand All @@ -47,19 +47,19 @@
</li>

<!-- node that replied to traceroute -->
<li v-if="this.traceRoute.from" class="relative flex gap-x-4">
<li v-if="traceRoute.from" class="relative flex gap-x-4">
<div class="absolute left-0 top-0 flex w-12 justify-center h-6">
<div class="w-px bg-gray-200"></div>
</div>
<div class="my-auto relative flex flex-none items-center justify-center">
<div>
<NodeIcon :node="findNodeById(this.traceRoute.from)"/>
<NodeIcon :node="findNodeById(traceRoute.from)"/>
</div>
</div>
<div class="flex-auto py-0.5 text-sm leading-5 text-gray-500">

<div class="font-medium text-gray-900">{{ getNodeLongName(this.traceRoute.from) || '???' }}</div>
<div>{{ getNodeHexId(this.traceRoute.from) }}</div>
<div class="font-medium text-gray-900">{{ getNodeLongName(traceRoute.from) || '???' }}</div>
<div>{{ getNodeHexId(traceRoute.from) }}</div>
<div>Replied to traceroute</div>
</div>
</li>
Expand All @@ -72,7 +72,7 @@
<div>
<div class="bg-gray-200 p-2 font-semibold">Raw Data</div>
<div class="text-sm text-gray-700">
<pre class="bg-white p-2 overflow-x-auto">{{ JSON.stringify(this.traceRoute, null, 4) }}</pre>
<pre class="bg-white p-2 overflow-x-auto">{{ JSON.stringify(traceRoute, null, 4) }}</pre>
</div>
</div>

Expand All @@ -91,6 +91,7 @@ import NodeIcon from "../nodes/NodeIcon.vue";
import moment from "moment";
import ChannelUtils from "../../js/ChannelUtils.js";
import TimeUtils from "../../js/TimeUtils.js";
import Database from "../../js/Database.js";
export default {
name: 'TraceRoutePage',
Expand All @@ -102,17 +103,23 @@ export default {
props: {
traceRouteId: String | Number,
},
data() {
return {
traceRoute: null,
traceRouteSubscription: null,
};
},
mounted() {
// redirect to main page if trace route not found
if(!this.traceRoute){
this.$router.push({
name: "main",
});
return;
}
// find trace route by id
this.traceRouteSubscription = Database.TraceRoute.findTraceRouteById(this.traceRouteId).$.subscribe((traceRoute) => {
this.traceRoute = traceRoute?.toJSON();
});
},
beforeUnmount() {
this.traceRouteSubscription?.unsubscribe();
},
methods: {
getNodeHexId: (nodeId) => NodeUtils.getNodeHexId(nodeId),
getNodeLongName: (nodeId) => NodeUtils.getNodeLongName(nodeId),
Expand All @@ -125,9 +132,6 @@ export default {
},
},
computed: {
traceRoute() {
return GlobalState.traceRoutesById[this.traceRouteId];
},
subtitle() {
if(this.traceRoute){
return `${this.getTimeAgo(this.traceRoute.rxTime)}${this.traceRoute.data.route.length} hop(s) on channel ${this.getChannelName(this.traceRoute.channel)}`;
Expand Down
5 changes: 2 additions & 3 deletions src/js/Connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,9 @@ class Connection {
});

// listen for trace routes
GlobalState.traceRoutesById = {};
connection.events.onTraceRoutePacket.subscribe((data) => {
connection.events.onTraceRoutePacket.subscribe(async (data) => {
console.log("onTraceRoutePacket", data);
GlobalState.traceRoutesById[data.id] = data;
await Database.TraceRoute.insert(data);
for(const traceRouteListener of this.traceRouteListeners){
try {
traceRouteListener(data);
Expand Down
Loading

0 comments on commit dc33f5e

Please sign in to comment.