Skip to content

Thread dump viewer - #14

Open
JugadK wants to merge 4 commits into
mainfrom
thread-dump-viewer
Open

Thread dump viewer#14
JugadK wants to merge 4 commits into
mainfrom
thread-dump-viewer

Conversation

@JugadK

@JugadK JugadK commented Jun 13, 2025

Copy link
Copy Markdown

Once our npm cache comes backup ill post a picture, but this adds a "grid" thread dump viewer to jifa

@JugadK
JugadK requested review from Copilot and jasonk000 June 13, 2025 01:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Adds a grid-based thread dump viewer to the Jifa UI and exposes a new endpoint in the analyzer to supply row data.

  • New ThreadViewerGrid.vue component renders threads in a sortable table and emits selections.
  • Updated ThreadDump.vue to fetch thread rows, integrate the grid view, and display code snippets for the selected thread.
  • Backend support via ThreadDumpRow model and rows() method in ThreadDumpAnalyzer to supply thread metadata and line ranges.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
frontend/src/components/threaddump/ThreadViewerGrid.vue New Vue component for grid-based thread listing and selection
frontend/src/components/threaddump/ThreadDump.vue Integrated grid view, fetch logic, and details panel
analysis/thread-dump/src/main/java/org/eclipse/jifa/tda/model/ThreadDumpRow.java Added data model for a thread dump row
analysis/thread-dump/src/main/java/org/eclipse/jifa/tda/ThreadDumpAnalyzer.java Added rows() to expose thread row data; adjusted imports

'javaMonitors',
'callSiteTree'
'callSiteTree',
'Table View',

Copilot AI Jun 13, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

activeNames includes the display title 'Table View', but the corresponding <el-collapse-item> uses the name 'emptyBox'. This mismatch prevents the grid tab from activating. Update activeNames to use 'emptyBox' or rename the collapse-item to 'Table View'.

Copilot uses AI. Check for mistakes.

console.log(thread)

if (lineNumberStart && lineNumberEnd) {

Copilot AI Jun 13, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking these values with a truthiness test fails when lineNumberStart is 0 (falsy). Use explicit checks like if (lineNumberStart != null && lineNumberEnd != null) { to handle zero-based lines.

Suggested change
if (lineNumberStart && lineNumberEnd) {
if (lineNumberStart != null && lineNumberEnd != null) {

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good bot

Comment thread frontend/src/components/threaddump/ThreadDump.vue Outdated
/**
* @return rows of a thread dump table
*/
public List<ThreadDumpRow> rows(PagingRequest paging) {

Copilot AI Jun 13, 2025

Copy link

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.

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +42
import java.util.*;
import java.util.stream.Collectors;

Copilot AI Jun 13, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Avoid wildcard imports; explicitly import only the needed classes to improve readability and prevent accidental dependencies.

Suggested change
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 uses AI. Check for mistakes.
Comment on lines +5 to +7
import lombok.Data;

@Data

Copilot AI Jun 13, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because there's an explicit all-args constructor, Lombok won’t generate a no-argument constructor. Add @NoArgsConstructor (or a manual default constructor) if your JSON serialization framework requires it.

Suggested change
import lombok.Data;
@Data
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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.*;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we undo this please?

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;

Copy link
Copy Markdown
Member

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.

*/
public List<ThreadDumpRow> rows(PagingRequest paging) {

List<ThreadDumpRow> threadDumpRows = new ArrayList<>(snapshot.getJavaThreads().stream().map(t -> {

Copy link
Copy Markdown
Member

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.

return new ThreadDumpRow(t.getName(), t.getId(), t.getOsThreadState(), 0, new Frame[]{}, t.getElapsed(), t.getCpu(), t.getLineStart(), t.getLineEnd());
}).toList();

threadDumpRows.addAll(nonJavaThreadDumpRows);

Copy link
Copy Markdown
Member

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.

Comment on lines +306 to +323
List<ThreadDumpRow> threadDumpRows = new ArrayList<>(snapshot.getJavaThreads().stream().map(t -> {

Frame[] frames = null;
int length = 0;

if (t.getTrace() != null) {
frames = t.getTrace().getFrames();
length = frames.length;
}

return new ThreadDumpRow(t.getName(), t.getId(), t.getOsThreadState(), length, frames, t.getElapsed(), t.getCpu(), t.getLineStart(), t.getLineEnd());
}).toList());

List<ThreadDumpRow> nonJavaThreadDumpRows = snapshot.getNonJavaThreads().stream().map(t -> {
return new ThreadDumpRow(t.getName(), t.getId(), t.getOsThreadState(), 0, new Frame[]{}, t.getElapsed(), t.getCpu(), t.getLineStart(), t.getLineEnd());
}).toList();

threadDumpRows.addAll(nonJavaThreadDumpRows);

Copy link
Copy Markdown
Member

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();

'javaMonitors',
'callSiteTree'
'callSiteTree',
'Table View',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Table View doesn't have the java camelCase approach.


console.log(thread)

if (lineNumberStart && lineNumberEnd) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good bot

});

request('rows').then((threadsData) => {
console.log(threadsData);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: is this required?

if (selectedThread.value) {
return row === selectedThread.value ? 'selected-row' : '';
} else {
return rowIndex === 0 ? 'selected-row' : '';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants