Skip to content

Commit e09290d

Browse files
committed
Added Timeout option to TRex Daemon
- Added asynchronomous call of TRex Start call (it can take long)
1 parent e98f2c1 commit e09290d

File tree

4 files changed

+141
-59
lines changed

4 files changed

+141
-59
lines changed

src/main/java/com/exalttech/trex/ui/controllers/daemon/TRexDaemonDialogController.java

Lines changed: 121 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.google.common.base.Charsets;
3131
import com.google.common.net.HttpHeaders;
3232
import com.google.common.net.MediaType;
33+
import javafx.concurrent.Task;
3334
import javafx.event.ActionEvent;
3435
import javafx.fxml.FXML;
3536
import javafx.fxml.Initializable;
@@ -56,6 +57,7 @@
5657
import java.text.MessageFormat;
5758
import java.util.*;
5859
import java.util.List;
60+
import java.util.concurrent.Callable;
5961

6062
/**
6163
* TRex Daemon FXM controller
@@ -87,6 +89,11 @@ public String pass(@NotNull String request) throws IOException {
8789
}
8890
}
8991

92+
@FunctionalInterface
93+
interface ExceptionHandler {
94+
void handle(Throwable ex);
95+
}
96+
9097
@FXML
9198
private ComboBox<String> hostnamesComboBox;
9299

@@ -117,6 +124,8 @@ public String pass(@NotNull String request) throws IOException {
117124
@FXML
118125
private Button startTRexButton;
119126

127+
@FXML TextField startTRexTimeoutTextField;
128+
120129
@FXML
121130
private Button loadDefaultConfigButton;
122131

@@ -130,21 +139,31 @@ public String pass(@NotNull String request) throws IOException {
130139

131140
private UserConfigModel userConfigModel;
132141
private String configFilename;
142+
private Task<Void> currentPendingTask;
133143

134144
private List<Control> controlsDisabledOnDisconnected;
135145
private List<Control> controlsDisabledOnConnected;
136146
private List<Control> controlsDisabledOnMetadataNotExists;
137147
private List<Control> controlsDisabledOnConfigInvalid;
138-
148+
private List<Control> controlsDisabledOnPendingTask;
139149
@Override
140150
public void initialize(URL location, ResourceBundle resources) {
141151
initHostnamesComboBox();
142152
controlsDisabledOnConnected = Arrays.asList(hostnamesComboBox, rpcPortTextField, connectButton);
143-
controlsDisabledOnDisconnected = Arrays.asList(disconnectButton, startTRexButton, stopTRexButton);
153+
controlsDisabledOnDisconnected = Arrays.asList(disconnectButton, startTRexButton, startTRexTimeoutTextField, stopTRexButton);
144154
controlsDisabledOnMetadataNotExists = Arrays.asList(configEditTitledPane, loadDefaultConfigButton);
145-
controlsDisabledOnConfigInvalid = Arrays.asList(startTRexButton);
155+
controlsDisabledOnConfigInvalid = Collections.singletonList(startTRexButton);
156+
controlsDisabledOnPendingTask = Arrays.asList(hostnamesComboBox, rpcPortTextField, connectButton, startTRexButton, startTRexTimeoutTextField, stopTRexButton, loadDefaultConfigButton);
157+
146158
configEditTitledPane.expandedProperty().bind(configEditTitledPane.disableProperty().not());
147-
this.configFilename = System.getProperty("user.name");
159+
configFilename = System.getProperty("user.name");
160+
161+
startTRexTimeoutTextField.textProperty().addListener((observable, oldValue, newValue) -> {
162+
if (!newValue.matches("\\d*")) {
163+
startTRexTimeoutTextField.setText(newValue.replaceAll("[^\\d]", ""));
164+
}
165+
});
166+
148167
refreshControlsAvailability();
149168
}
150169

@@ -208,6 +227,12 @@ private void refreshControlsAvailability() {
208227
control.setDisable(true);
209228
}
210229
}
230+
231+
if (currentPendingTask != null) {
232+
for (Control control : controlsDisabledOnPendingTask) {
233+
control.setDisable(true);
234+
}
235+
}
211236
}
212237

213238
private boolean isConnected() {
@@ -216,6 +241,12 @@ private boolean isConnected() {
216241

217242
private void disconnect() {
218243
if (isConnected()) {
244+
245+
if (currentPendingTask != null){
246+
currentPendingTask.cancel();
247+
currentPendingTask = null;
248+
}
249+
219250
client = null;
220251
metadata = null;
221252

@@ -256,6 +287,10 @@ private String getPort() {
256287
return rpcPortTextField.getText();
257288
}
258289

290+
private Integer getStartTimeout() {
291+
return Integer.valueOf(startTRexTimeoutTextField.getText());
292+
}
293+
259294
private String getHostname() {
260295
return hostnamesComboBox.getSelectionModel().getSelectedItem();
261296
}
@@ -291,58 +326,93 @@ private void getMetadata() {
291326
}
292327

293328
private void startTRex() {
294-
Boolean configUploaded = false;
295-
try {
296-
configUploaded = client.createRequest()
297-
.id(getId())
298-
.method("push_file")
299-
.param("filename", configFilename)
300-
.param("bin_data", Base64.getEncoder().encodeToString(
301-
userConfigModel.getYAMLString().getBytes(Charsets.US_ASCII)))
302-
.returnAs(Boolean.class)
303-
.execute();
304-
305-
if (!configUploaded) {
306-
log(LogType.ERROR, "Config upload to TRex host failed (TRex Daemon IO error)");
307-
}
329+
scheduleTask(() -> {
330+
try {
331+
Boolean configUploaded = client.createRequest()
332+
.id(getId())
333+
.method("push_file")
334+
.param("filename", configFilename)
335+
.param("bin_data", Base64.getEncoder().encodeToString(
336+
userConfigModel.getYAMLString().getBytes(Charsets.US_ASCII)))
337+
.returnAs(Boolean.class)
338+
.execute();
339+
340+
if (!configUploaded) {
341+
throw new RuntimeException("Config upload to TRex host failed (TRex Daemon IO error)");
342+
}
343+
344+
log(LogType.INFO, "Config was uploaded successfully");
345+
} catch (RuntimeException ex) {
346+
throw new RuntimeException(MessageFormat.format("Config upload to TRex host failed: {0}", ex));
347+
} catch (JsonProcessingException ex) {
348+
throw new RuntimeException(MessageFormat.format("Config serialization failed: {0}", ex));
349+
}
350+
351+
Map<String, Object> cmdParams = new HashMap<>();
352+
try {
353+
String files_path = client.createRequest()
354+
.id(getId())
355+
.method("get_files_path")
356+
.returnAs(String.class)
357+
.execute();
358+
359+
cmdParams.put("cfg", FilenameUtils.separatorsToUnix(Paths.get(files_path, configFilename).toString()));
360+
} catch (RuntimeException ex) {
361+
throw new RuntimeException(MessageFormat.format("Unable to get user configs path: {0}", ex));
362+
}
363+
364+
try {
365+
log(LogType.INFO, MessageFormat.format("Starting TRex... (timeout is {0} sec)", getStartTimeout()));
366+
client.createRequest()
367+
.id(getId())
368+
.method("start_trex")
369+
.param("trex_cmd_options", cmdParams)
370+
.param("user", System.getProperty("user.name"))
371+
.param("stateless", true)
372+
.returnAs(Integer.class)
373+
.param("timeout", getStartTimeout())
374+
.execute();
375+
376+
} catch (RuntimeException ex) {
377+
throw new RuntimeException(MessageFormat.format("Unable to start TRex: {0} ", ex));
378+
}
379+
return null;
380+
},
381+
ex -> log(LogType.ERROR, ex.getMessage()),
382+
() -> log(LogType.INFO, "TRex was started successfully"),
383+
() -> log(LogType.WARNING, "TRex start was cancelled")
384+
);
385+
}
308386

309-
log(LogType.INFO, "Config uploaded successfully");
310-
} catch (RuntimeException ex) {
311-
log(LogType.ERROR, MessageFormat.format("Config upload to TRex host failed: {0}", ex));
312-
} catch (JsonProcessingException ex) {
313-
log(LogType.ERROR, MessageFormat.format("Config serialization failed: {0}", ex));
387+
private void scheduleTask(Callable<Void> mainAction, ExceptionHandler onException, Runnable onSucceed, Runnable onCanceled) {
388+
if (currentPendingTask != null) {
389+
currentPendingTask.cancel();
314390
}
315391

316-
Map<String, Object> cmdParams = new HashMap<>();
317-
318-
if (configUploaded) {
319-
try {
320-
String files_path = client.createRequest()
321-
.id(getId())
322-
.method("get_files_path")
323-
.returnAs(String.class)
324-
.execute();
325-
326-
cmdParams.put("cfg", FilenameUtils.separatorsToUnix(Paths.get(files_path, configFilename).toString()));
327-
} catch (RuntimeException ex) {
328-
log(LogType.ERROR, MessageFormat.format("Unable to get user configs path: {0}", ex));
392+
currentPendingTask = new Task<Void>() {
393+
@Override
394+
protected Void call() throws Exception {
395+
return mainAction.call();
329396
}
330-
}
397+
};
398+
currentPendingTask.setOnFailed(event -> {
399+
onException.handle(currentPendingTask.getException());
400+
currentPendingTask = null;
401+
refreshControlsAvailability();
402+
});
403+
currentPendingTask.setOnSucceeded(event -> {
404+
onSucceed.run();
405+
currentPendingTask = null;
406+
refreshControlsAvailability();
407+
});
408+
currentPendingTask.setOnCancelled(event -> {
409+
onCanceled.run();
410+
currentPendingTask = null;
411+
refreshControlsAvailability();
412+
});
331413

332-
try {
333-
Integer trexSessionHandler = client.createRequest()
334-
.id(getId())
335-
.method("start_trex")
336-
.param("trex_cmd_options", cmdParams)
337-
.param("user", System.getProperty("user.name"))
338-
.param("stateless", true)
339-
.returnAs(Integer.class)
340-
.param("timeout", 15)
341-
.execute();
342-
log(LogType.INFO, "TRex started successfully");
343-
} catch (RuntimeException ex) {
344-
log(LogType.ERROR, MessageFormat.format("Unable to start TRex: {0} ", ex));
345-
}
414+
new Thread(currentPendingTask).start();
415+
refreshControlsAvailability();
346416
}
347417

348418
private void stopTRex() {

src/main/java/com/exalttech/trex/ui/views/logs/LogType.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ public enum LogType {
3131
*
3232
*/
3333
INFO("Info ", "logInfo"),
34+
/**
35+
*
36+
*/
37+
WARNING("Warning ", "logWarning"),
3438
/**
3539
*
3640
*/

src/main/resources/fxml/TRexDaemonDialog.fxml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<?import javafx.scene.control.TitledPane?>
1313
<?import javafx.scene.layout.AnchorPane?>
1414
<?import javafx.scene.layout.HBox?>
15+
<?import javafx.scene.layout.Region?>
1516
<?import javafx.scene.layout.VBox?>
1617

1718
<?import com.exalttech.trex.ui.views.logs.LogsView?>
@@ -36,7 +37,7 @@
3637
<Insets bottom="5.0" left="15.0" right="5.0" top="5.0" />
3738
</padding>
3839
</Label>
39-
<TextField fx:id="rpcPortTextField" text="8090">
40+
<TextField fx:id="rpcPortTextField" maxWidth="60.0" text="8090">
4041
<HBox.margin>
4142
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
4243
</HBox.margin>
@@ -52,12 +53,6 @@
5253
</HBox.margin>
5354
</Button>
5455
</children>
55-
<VBox.margin>
56-
<Insets />
57-
</VBox.margin>
58-
<opaqueInsets>
59-
<Insets />
60-
</opaqueInsets>
6156
</HBox>
6257
<TitledPane fx:id="configEditTitledPane" animated="true" text="TRex config edit">
6358
<content>
@@ -106,13 +101,23 @@
106101
</Tab>
107102
</tabs>
108103
</TabPane>
109-
<HBox alignment="TOP_RIGHT" VBox.vgrow="NEVER">
104+
<HBox alignment="CENTER_RIGHT" VBox.vgrow="NEVER">
110105
<children>
111106
<Button fx:id="stopTRexButton" mnemonicParsing="false" onAction="#handleStopClicked" styleClass="normalButton" text="Stop">
112107
<HBox.margin>
113108
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
114109
</HBox.margin>
115110
</Button>
111+
<Label text="Start timeout">
112+
<padding>
113+
<Insets bottom="5.0" left="15.0" right="5.0" top="5.0" />
114+
</padding>
115+
</Label>
116+
<TextField fx:id="startTRexTimeoutTextField" maxWidth="60.0" text="40">
117+
<HBox.margin>
118+
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
119+
</HBox.margin>
120+
</TextField>
116121
<Button fx:id="startTRexButton" mnemonicParsing="false" onAction="#handleStartClicked" styleClass="normalButton" text="Start">
117122
<HBox.margin>
118123
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />

src/main/resources/styles/mainStyle.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,9 @@ connectContent .titled-pane:focused .title .arrow-button .arrow {
878878
.logInfo{
879879
-fx-text-fill:#29bf4c;
880880
}
881+
.logWarning{
882+
-fx-text-fill:#ff9514;
883+
}
881884
.logError{
882885
-fx-text-fill:#ea2323;
883886
}

0 commit comments

Comments
 (0)