Skip to content

Commit

Permalink
Added Freeze function, fix for #78
Browse files Browse the repository at this point in the history
The Freeze function, activated with a button (clock icon), makes the UI
stop updating the live profile. The incoming changes are still being
stored, the UI just doesn't react to it any more.

When the profile is unfrozen, the UI starts updating again and jumps to
the most recently received profile information.
  • Loading branch information
arickp authored and arickp committed Jan 3, 2017
1 parent eb86c32 commit 53184da
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 16 deletions.
Expand Up @@ -27,8 +27,10 @@
import static com.insightfullogic.honest_profiler.ports.javafx.util.report.ReportUtil.writeFlatProfileCsv;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.COMPARE_16;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.EXPORT_16;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.FREEZE_16;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.FUNNEL_16;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.FUNNEL_ACTIVE_16;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.UNFREEZE_16;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.viewFor;

import java.util.ArrayList;
Expand All @@ -46,6 +48,7 @@
import com.insightfullogic.honest_profiler.ports.javafx.model.task.CopyAndFilterProfile;
import com.insightfullogic.honest_profiler.ports.javafx.util.DialogUtil;
import com.insightfullogic.honest_profiler.ports.javafx.util.report.ReportUtil;
import com.insightfullogic.honest_profiler.ports.javafx.view.Icon;
import com.insightfullogic.honest_profiler.ports.javafx.view.Rendering;
import com.insightfullogic.honest_profiler.ports.javafx.view.cell.GraphicalShareTableCell;
import com.insightfullogic.honest_profiler.ports.javafx.view.cell.MethodNameTableCell;
Expand Down Expand Up @@ -111,7 +114,9 @@ protected void initialize()
info(filterButton, "Specify filters restricting the visible entries");
info(compareButton, "Click to select another open profile to compare this profile against");
info(exportButton, "Export the visible entries to a CSV file");
info(quickFilterText, "Specify text for quickly filtering the Fully Qualified Method Name (= <fully_qualified_class_name>.<method_name>)");
info(
quickFilterText,
"Specify text for quickly filtering the Fully Qualified Method Name (= <fully_qualified_class_name>.<method_name>)");
info(quickFilterButton, "Apply the Quick Filter");
info(flatProfileView, "Shows methods and their Self and Total usage percentages");

Expand All @@ -120,14 +125,13 @@ protected void initialize()

exportButton.setGraphic(viewFor(EXPORT_16));
exportButton.setTooltip(new Tooltip("Export the current view to a file"));
exportButton.setOnAction(event ->

showExportDialog(
exportButton.setOnAction(event -> showExportDialog(
exportButton.getScene().getWindow(),
"flat_profile.csv",
out -> writeFlatProfileCsv(out, flatProfile, ReportUtil.Mode.CSV)
));


initializeComparison();
initializeFilter();
initializeTable();
Expand Down
Expand Up @@ -19,23 +19,33 @@
package com.insightfullogic.honest_profiler.ports.javafx.controller;

import static com.insightfullogic.honest_profiler.ports.javafx.ViewType.FLAT;
import static com.insightfullogic.honest_profiler.ports.javafx.model.ProfileContext.ProfileMode.LIVE;
import static com.insightfullogic.honest_profiler.ports.javafx.util.ConversionUtil.getStringConverterForType;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.FREEZE_16;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.UNFREEZE_16;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.viewFor;

import com.insightfullogic.honest_profiler.ports.javafx.ViewType;
import com.insightfullogic.honest_profiler.ports.javafx.model.ApplicationContext;
import com.insightfullogic.honest_profiler.ports.javafx.model.ProfileContext;
import com.insightfullogic.honest_profiler.ports.javafx.model.ProfileContext.ProfileMode;
import com.insightfullogic.honest_profiler.ports.javafx.view.Icon;

import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.AnchorPane;

public class ProfileRootController extends AbstractController
{
@FXML
private ChoiceBox<ViewType> viewChoice;
@FXML
private Button freezeButton;
@FXML
private Label traceCount;
@FXML
private AnchorPane content;
Expand All @@ -46,13 +56,47 @@ public class ProfileRootController extends AbstractController
@FXML
private FlameViewController flameController;

private ProfileContext profileContext;

@FXML
public void initialize()
{
info(
viewChoice,
"Select the View : Flat View lists all methods as a list; Tree View shows the stack trees per thread; Flame View shows the Flame Graph");
info(
freezeButton,
"Freeze a live profile. The view will not update when new profiling information is available.");
info(traceCount, "Shows the number of samples in the profile");

freezeButton.setGraphic(viewFor(FREEZE_16));
freezeButton.setDisable(true);
freezeButton.setTooltip(new Tooltip("Freeze the live profile."));
info(
freezeButton,
"Freeze the live profile. The view will not update when new profiling information is available.");

freezeButton.setOnAction(event ->
{
if (profileContext.isFrozen())
{
profileContext.setFrozen(false);
freezeButton.setGraphic(viewFor(FREEZE_16));
freezeButton.setTooltip(new Tooltip("Freeze the live profile"));
info(
freezeButton,
"Freeze the live profile. The view will not update when new profiling information is available.");
}
else
{
profileContext.setFrozen(true);
freezeButton.setGraphic(viewFor(UNFREEZE_16));
freezeButton.setTooltip(new Tooltip("Unfreeze the live profile"));
info(
freezeButton,
"Unfreeze the live profile. The view will update again when new profiling information is available.");
}
});
}

// Instance Accessors
Expand All @@ -68,6 +112,8 @@ public void setApplicationContext(ApplicationContext applicationContext)

public void setProfileContext(ProfileContext profileContext)
{
this.profileContext = profileContext;

flatController.setProfileContext(profileContext);
treeController.setProfileContext(profileContext);
flameController.setProfileContext(profileContext);
Expand All @@ -86,6 +132,8 @@ public void setProfileContext(ProfileContext profileContext)
viewChoice.getSelectionModel().selectedItemProperty()
.addListener((property, oldValue, newValue) -> show(newValue));
viewChoice.getSelectionModel().select(FLAT);

freezeButton.setDisable(profileContext.getMode() != LIVE);
}

// View Switch
Expand Down
Expand Up @@ -31,6 +31,10 @@ public static enum ProfileMode
private final SimpleObjectProperty<Profile> profile;
private final SimpleObjectProperty<FlameGraph> flameGraph;

private boolean frozen;
private Profile frozenProfile;
private FlameGraph frozenFlameGraph;

public ProfileContext(String name, ProfileMode mode)
{
id = counter.incrementAndGet();
Expand Down Expand Up @@ -75,6 +79,31 @@ public ObjectProperty<FlameGraph> flameGraphProperty()
return flameGraph;
}

public boolean isFrozen()
{
return frozen;
}

// Call only on FX Thread !
public void setFrozen(boolean frozen)
{
if (!frozen)
{
if (frozenProfile != null)
{
update(frozenProfile);
frozenProfile = null;
}

if (frozenFlameGraph != null)
{
update(frozenFlameGraph);
frozenFlameGraph = null;
}
}
this.frozen = frozen;
}

public ProfileListener getProfileListener()
{
return new ProfileListener()
Expand All @@ -84,11 +113,11 @@ public void accept(Profile t)
{
if (isFxApplicationThread())
{
profile.set(t);
update(t);
}
else
{
runLater(() -> profile.set(t));
runLater(() -> update(t));
}
}
};
Expand All @@ -103,13 +132,38 @@ public void accept(FlameGraph t)
{
if (isFxApplicationThread())
{
flameGraph.set(t);
update(t);
}
else
{
runLater(() -> flameGraph.set(t));
runLater(() -> update(t));
}
}
};
}

// Call only on FX Thread !
private void update(Profile t)
{
if (frozen)
{
frozenProfile = t;
}
else
{
profile.set(t);
}
}

private void update(FlameGraph t)
{
if (frozen)
{
frozenFlameGraph = t;
}
else
{
flameGraph.set(t);
}
}
}
Expand Up @@ -23,6 +23,9 @@ public final class Icon
public static final Image LIVE_16 = toImage(ICON_16_DIR + "monitor.png");
public static final Image LOG_16 = toImage(ICON_16_DIR + "document-binary.png");

public static final Image FREEZE_16 = toImage(ICON_16_DIR + "clock.png");
public static final Image UNFREEZE_16 = toImage(ICON_16_DIR + "clock--exclamation.png");

private static Image toImage(String resource)
{
return new Image(Icon.class.getResourceAsStream(resource));
Expand Down
Expand Up @@ -17,10 +17,10 @@
<children>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="25.0" minWidth="25.0" prefWidth="25.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="25.0" minWidth="25.0" prefWidth="25.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="25.0" minWidth="25.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="25.0" minWidth="25.0" prefWidth="100.0" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" maxWidth="25.0" minWidth="25.0" prefWidth="25.0" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" maxWidth="25.0" minWidth="25.0" prefWidth="25.0" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" maxWidth="25.0" minWidth="25.0" prefWidth="25.0" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" maxWidth="25.0" minWidth="25.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="200.0" minWidth="25.0" prefWidth="200.0" />
</columnConstraints>
<rowConstraints>
Expand Down
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
Expand All @@ -12,6 +13,7 @@
<HBox alignment="CENTER_LEFT" maxHeight="35.0" minHeight="35.0" prefHeight="35.0" prefWidth="200.0" spacing="5.0" VBox.vgrow="NEVER">
<children>
<ChoiceBox fx:id="viewChoice" maxHeight="25.0" minHeight="25.0" prefHeight="25.0" />
<Button fx:id="freezeButton" maxHeight="20.0" maxWidth="20.0" minHeight="20.0" minWidth="20.0" mnemonicParsing="false" prefHeight="20.0" prefWidth="20.0" />
<Label fx:id="traceCount" prefHeight="15.0" prefWidth="104.0" />
</children>
<VBox.margin>
Expand Down
Expand Up @@ -17,10 +17,10 @@
<children>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="25.0" minWidth="25.0" prefWidth="25.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="25.0" minWidth="25.0" prefWidth="25.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="25.0" minWidth="25.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="25.0" minWidth="25.0" prefWidth="100.0" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" maxWidth="25.0" minWidth="25.0" prefWidth="25.0" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" maxWidth="25.0" minWidth="25.0" prefWidth="25.0" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" maxWidth="25.0" minWidth="25.0" prefWidth="25.0" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" maxWidth="25.0" minWidth="25.0" prefWidth="25.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="200.0" minWidth="25.0" prefWidth="200.0" />
</columnConstraints>
<rowConstraints>
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 53184da

Please sign in to comment.