-
Notifications
You must be signed in to change notification settings - Fork 6
Thread dump viewer #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -22,14 +22,9 @@ | |||||||||||||||||||||||
| import org.eclipse.jifa.common.domain.vo.PageView; | ||||||||||||||||||||||||
| import org.eclipse.jifa.common.util.PageViewBuilder; | ||||||||||||||||||||||||
| import org.eclipse.jifa.tda.enums.MonitorState; | ||||||||||||||||||||||||
| import org.eclipse.jifa.tda.enums.OSTreadState; | ||||||||||||||||||||||||
| import org.eclipse.jifa.tda.enums.ThreadType; | ||||||||||||||||||||||||
| import org.eclipse.jifa.tda.model.CallSiteTree; | ||||||||||||||||||||||||
| import org.eclipse.jifa.tda.model.Frame; | ||||||||||||||||||||||||
| import org.eclipse.jifa.tda.model.IdentityPool; | ||||||||||||||||||||||||
| import org.eclipse.jifa.tda.model.JavaThread; | ||||||||||||||||||||||||
| import org.eclipse.jifa.tda.model.Monitor; | ||||||||||||||||||||||||
| import org.eclipse.jifa.tda.model.RawMonitor; | ||||||||||||||||||||||||
| import org.eclipse.jifa.tda.model.Snapshot; | ||||||||||||||||||||||||
| import org.eclipse.jifa.tda.model.*; | ||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we undo this please? |
||||||||||||||||||||||||
| import org.eclipse.jifa.tda.model.Thread; | ||||||||||||||||||||||||
| import org.eclipse.jifa.tda.parser.ParserFactory; | ||||||||||||||||||||||||
| import org.eclipse.jifa.tda.util.CollectionUtil; | ||||||||||||||||||||||||
|
|
@@ -43,11 +38,8 @@ | |||||||||||||||||||||||
| import java.io.IOException; | ||||||||||||||||||||||||
| import java.io.LineNumberReader; | ||||||||||||||||||||||||
| import java.nio.file.Path; | ||||||||||||||||||||||||
| import java.util.ArrayList; | ||||||||||||||||||||||||
| import java.util.Collections; | ||||||||||||||||||||||||
| import java.util.HashMap; | ||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||
| import java.util.Map; | ||||||||||||||||||||||||
| import java.util.*; | ||||||||||||||||||||||||
| import java.util.stream.Collectors; | ||||||||||||||||||||||||
|
Comment on lines
+41
to
+42
|
||||||||||||||||||||||||
| import java.util.*; | |
| import java.util.stream.Collectors; | |
| import java.util.ArrayList; | |
| import java.util.HashMap; | |
| import java.util.List; | |
| import java.util.Map; | |
| import java.util.Optional; | |
| import java.util.Set; | |
| import java.util.function.Function; | |
| import java.util.stream.Collectors; | |
| import java.util.stream.Collectors; |
Copilot
AI
Jun 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The paging parameter is currently unused. Either implement pagination logic inside this method or remove the parameter to keep the API signature accurate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style:
We can add static functions and/or local functions somewhere to do this conversion. For example, a ThreadDumpRow(JavaThread javaThread) constructor or a static ThreadDumpRow fromJavaThread(JavaThread javaThread).
Though, it's a bit clunky having that in the Model, so maybe somewhere here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to simply construct the paging component using PageViewer, see the function buildVThreadPageView for an example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach generates quite a bit of intermediary list garbage. Consider something like this instead:
Stream<ThreadDumpRow> javaRows = snapshot.getJavaThreads().stream().map(....);
Stream<ThreadDumpRow> nonJavaRows = snapshot.getNonJavaThreads().stream().map(....);
Stream<ThreadDumpRow> allRows = Stream.concat(javaRows, nonJavaRows);
// consider implementing paging here on the stream
List<ThreadRumpRow> threadDumpRows = allRows.toList();
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,39 @@ | ||||||||||||||||||
| package org.eclipse.jifa.tda.model; | ||||||||||||||||||
|
|
||||||||||||||||||
| import org.eclipse.jifa.tda.enums.OSTreadState; | ||||||||||||||||||
|
|
||||||||||||||||||
| import lombok.Data; | ||||||||||||||||||
|
|
||||||||||||||||||
| @Data | ||||||||||||||||||
|
Comment on lines
+5
to
+7
|
||||||||||||||||||
| import lombok.Data; | |
| @Data | |
| import lombok.Data; | |
| import lombok.NoArgsConstructor; | |
| @Data | |
| @NoArgsConstructor |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -28,6 +28,7 @@ import Content from '@/components/threaddump/Content.vue'; | |||||
| import Thread from '@/components/threaddump/Thread.vue'; | ||||||
| import Monitor from '@/components/threaddump/Monitor.vue'; | ||||||
| import CallSiteTree from '@/components/threaddump/CallSiteTree.vue'; | ||||||
| import ThreadViewerGrid from '@/components/threaddump/ThreadViewerGrid.vue'; | ||||||
|
|
||||||
| const { request } = useAnalysisApiRequester(); | ||||||
|
|
||||||
|
|
@@ -36,7 +37,9 @@ const activeNames = ref<string[]>([ | |||||
| 'threadSummary', | ||||||
| 'threadGroupSummary', | ||||||
| 'javaMonitors', | ||||||
| 'callSiteTree' | ||||||
| 'callSiteTree', | ||||||
| 'Table View', | ||||||
|
||||||
| 'fileContent' | ||||||
| ]); | ||||||
|
|
||||||
| const deadLockCount = ref(0); | ||||||
|
|
@@ -66,6 +69,10 @@ const threadDialogVisible = ref(false); | |||||
| const selectedThreadType = ref(); | ||||||
| const selectedThreadGroup = ref(); | ||||||
|
|
||||||
| const threadsArray = ref([]); | ||||||
| const selectedThread = ref<any>(null); | ||||||
| const selectedThreadContent = ref(''); | ||||||
|
|
||||||
| function sum(arr) { | ||||||
| return arr.reduce((l, r) => l + r); | ||||||
| } | ||||||
|
|
@@ -92,6 +99,20 @@ function showThreadsOfGroup(group) { | |||||
| threadDialogVisible.value = true; | ||||||
| } | ||||||
|
|
||||||
| function onThreadSelected(thread) { | ||||||
| selectedThread.value = thread; | ||||||
| const lineNumberStart = thread.lineNumberStart; | ||||||
| const lineNumberEnd = thread.lineNumberEnd; | ||||||
| if (lineNumberStart && lineNumberEnd) { | ||||||
|
||||||
| if (lineNumberStart && lineNumberEnd) { | |
| if (lineNumberStart != null && lineNumberEnd != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good bot
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: is this required?
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| <!-- | ||
| Copyright (c) 2023, 2024 Contributors to the Eclipse Foundation | ||
|
|
||
| See the NOTICE file(s) distributed with this work for additional | ||
| information regarding copyright ownership. | ||
|
|
||
| This program and the accompanying materials are made available under the | ||
| terms of the Eclipse Public License 2.0 which is available at | ||
| http://www.eclipse.org/legal/epl-2.0 | ||
|
|
||
| SPDX-License-Identifier: EPL-2.0 | ||
| --> | ||
| <script setup lang="ts"> | ||
| import { ref } from 'vue'; | ||
|
|
||
| const props = defineProps<{ | ||
| threads: { | ||
| tid: string; | ||
| name: string; | ||
| state: string; | ||
| stackDepth: number; | ||
| frames: any[]; | ||
| cpuTime: string; | ||
| elapsedTime: string; | ||
| }[]; | ||
| }>(); | ||
|
|
||
| const emit = defineEmits(['row-click']); | ||
|
|
||
| const selectedThread = ref(null); | ||
|
|
||
| function onRowClick(row) { | ||
| emit('row-click', row); | ||
| selectedThread.value = row; | ||
| } | ||
|
|
||
| function rowClassName({ row, rowIndex }) { | ||
| if (selectedThread.value) { | ||
| return row === selectedThread.value ? 'selected-row' : ''; | ||
| } else { | ||
| return rowIndex === 0 ? 'selected-row' : ''; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe not clear what the intent is here, are we defaulting to first-row selected deliberately? |
||
| } | ||
| } | ||
| </script> | ||
|
|
||
| <template> | ||
| <el-table :data="props.threads" stripe @row-click="onRowClick" :row-class-name="rowClassName"> | ||
| <el-table-column prop="name" label="Name" sortable /> | ||
| <el-table-column prop="state" label="State" sortable /> | ||
| <el-table-column prop="stackDepth" label="Stack Depth" sortable /> | ||
| <el-table-column prop="cpuTime" label="CPU Time (ms)" sortable /> | ||
| <el-table-column prop="elapsedTime" label="Elapsed Time (ms)" sortable /> | ||
| </el-table> | ||
|
|
||
| <div v-if="selectedThread" class="thread-details"> | ||
| </div> | ||
| </template> | ||
|
|
||
| <style scoped> | ||
| .selected-row { | ||
| border: 2px solid #409EFF; | ||
| } | ||
| </style> | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: typo
We should submit a separate PR upstream to rename it.