Skip to content

Commit

Permalink
Merge pull request #3066 from ControlSystemStudio/CSSTUDIIO-2467
Browse files Browse the repository at this point in the history
Take snapshot on server
  • Loading branch information
shroffk authored Jul 17, 2024
2 parents 6a6c5be + d6dd63a commit 74bded8
Show file tree
Hide file tree
Showing 18 changed files with 551 additions and 283 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ public class Messages {
public static String tagCommentLabel;
public static String tagRemoveConfirmationTitle;
public static String tagRemoveConfirmationContent;
public static String takeSnapshotFailed;
public static String timestamp;

public static String toolTipTableColumnPVName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,11 @@ public interface SaveAndRestoreClient {
* @return A @{@link List} of {@link RestoreResult}s with information on potentially failed {@link SnapshotItem}s.
*/
List<RestoreResult> restore(String snapshotNodeId);

/**
* Requests service to take a snapshot.
* @param configurationNodeId The unique id of the {@link Configuration} for which to take the snapshot
* @return A {@link List} of {@link SnapshotItem}s carrying snapshot values read by the service.
*/
List<SnapshotItem> takeSnapshot(String configurationNodeId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,6 @@ public List<RestoreResult> restore(List<SnapshotItem> snapshotItems){
});
}


public List<RestoreResult> restore(String snapshotNodeId){
WebResource webResource =
getClient()
Expand All @@ -689,4 +688,29 @@ public List<RestoreResult> restore(String snapshotNodeId){
return response.getEntity(new GenericType<>() {
});
}

@Override
public List<SnapshotItem> takeSnapshot(String configNodeId){
WebResource webResource =
getClient()
.resource(Preferences.jmasarServiceUrl + "/take-snapshot/" + configNodeId);
ClientResponse response;
try {
response = webResource.accept(CONTENT_TYPE_JSON)
.get(ClientResponse.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
if (response.getStatus() != ClientResponse.Status.OK.getStatusCode()) {
String message = "Take snapshot failed";
try {
message = new String(response.getEntityInputStream().readAllBytes());
} catch (IOException e) {
logger.log(Level.WARNING, "Unable to parse response", e);
}
throw new SaveAndRestoreClientException(message);
}
return response.getEntity(new GenericType<>() {
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -416,4 +416,15 @@ public List<RestoreResult> restore(String snapshotNodeId) throws Exception{
executor.submit(() -> saveAndRestoreClient.restore(snapshotNodeId));
return future.get();
}

/**
* Requests service to take a snapshot, i.e. to read PVs as defined in a {@link Configuration}.
* @param configurationNodeId The unique id of the {@link Configuration} for which to take the snapshot
* @return A {@link List} of {@link SnapshotItem}s carrying snapshot values read by the service.
*/
public List<SnapshotItem> takeSnapshot(String configurationNodeId) throws Exception{
Future<List<SnapshotItem>> future =
executor.submit(() -> saveAndRestoreClient.takeSnapshot(configurationNodeId));
return future.get();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ protected void showSnapshotInTable(Snapshot snapshot) {
});

connectPVs();

updateTable(null);
}

Expand All @@ -294,21 +295,21 @@ protected void showSnapshotInTable(Snapshot snapshot) {
public void updateTable(List<TableEntry> entries) {
final ObservableList<TableEntry> items = snapshotTableView.getItems();
final boolean notHide = !snapshotController.isHideEqualItems();
snapshotTableView.getItems().clear();
tableEntryItems.entrySet().forEach(e -> {
items.clear();
tableEntryItems.forEach((key, value) -> {
// there is no harm if this is executed more than once, because only one line is allowed for these
// two properties (see SingleListenerBooleanProperty for more details)
e.getValue().liveStoredEqualProperty().addListener((a, o, n) -> {
value.liveStoredEqualProperty().addListener((a, o, n) -> {
if (snapshotController.isHideEqualItems()) {
if (n) {
snapshotTableView.getItems().remove(e.getValue());
snapshotTableView.getItems().remove(value);
} else {
snapshotTableView.getItems().add(e.getValue());
snapshotTableView.getItems().add(value);
}
}
});
if (notHide || !e.getValue().liveStoredEqualProperty().get()) {
items.add(e.getValue());
if (notHide || !value.liveStoredEqualProperty().get()) {
items.add(value);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ public void takeSnapshot() {
snapshotTab.setText(Messages.unnamedSnapshot);
snapshotTableViewController.takeSnapshot(snapshot -> {
disabledUi.set(false);
snapshotProperty.set(snapshot);
if(snapshot != null){
snapshotProperty.set(snapshot);
}
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,17 @@
import org.phoebus.core.vtypes.VTypeHelper;
import org.phoebus.framework.jobs.JobManager;
import org.phoebus.ui.dialog.DialogHelper;
import org.phoebus.ui.dialog.ExceptionDetailsErrorDialog;
import org.phoebus.util.time.TimestampFormats;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.logging.Level;
Expand Down Expand Up @@ -183,71 +181,39 @@ public void updateItem(final Boolean item, final boolean empty) {
}

public void takeSnapshot(Consumer<Snapshot> consumer) {
// Clear snapshots array
snapshots.clear();
List<SnapshotItem> entries = new ArrayList<>();
readAll(list ->
Platform.runLater(() -> {
tableEntryItems.clear();
entries.addAll(list);
Snapshot snapshot = new Snapshot();
snapshot.setSnapshotNode(Node.builder().nodeType(NodeType.SNAPSHOT).build());
SnapshotData snapshotData = new SnapshotData();
snapshotData.setSnapshotItems(entries);
snapshot.setSnapshotData(snapshotData);
showSnapshotInTable(snapshot);
if (!Preferences.default_snapshot_name_date_format.isEmpty()) {
SimpleDateFormat formatter = new SimpleDateFormat(Preferences.default_snapshot_name_date_format);
snapshot.getSnapshotNode().setName(formatter.format(new Date()));
}
consumer.accept(snapshot);
})
);
}

/**
* Reads all PVs using a thread pool. All reads are asynchronous, waiting at most the amount of time
* configured through a preference setting.
*
* @param completion Callback receiving a list of {@link SnapshotItem}s where values for PVs that could
* not be read are set to {@link org.phoebus.applications.saveandrestore.ui.VDisconnectedData#INSTANCE}.
*/
private void readAll(Consumer<List<SnapshotItem>> completion) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
SnapshotItem[] snapshotEntries = new SnapshotItem[tableEntryItems.values().size()];
JobManager.schedule("Take snapshot", monitor -> {
final CountDownLatch countDownLatch = new CountDownLatch(tableEntryItems.values().size());
for (TableEntry t : tableEntryItems.values()) {
// Submit read request only if job has not been cancelled
executorService.submit(() -> {
SaveAndRestorePV pv = pvs.get(getPVKey(t.pvNameProperty().get(), t.readOnlyProperty().get()));
VType value = VDisconnectedData.INSTANCE;
try {
value = pv.getPv().asyncRead().get(Preferences.readTimeout, TimeUnit.MILLISECONDS);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Failed to read PV " + pv.getPvName(), e);
}
VType readBackValue = VDisconnectedData.INSTANCE;
if (pv.getReadbackPv() != null && !pv.getReadbackValue().equals(VDisconnectedData.INSTANCE)) {
try {
readBackValue = pv.getReadbackPv().asyncRead().get(Preferences.readTimeout, TimeUnit.MILLISECONDS);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Failed to read read-back PV " + pv.getReadbackPvName(), e);
}
}
SnapshotItem snapshotItem = new SnapshotItem();
snapshotItem.setConfigPv(t.getConfigPv());
snapshotItem.setValue(value);
snapshotItem.setReadbackValue(readBackValue);

snapshotEntries[t.idProperty().get() - 1] = snapshotItem;
countDownLatch.countDown();
});
// Clear snapshots array
snapshots.clear();
List<SnapshotItem> snapshotItems;
try {
snapshotItems = SaveAndRestoreService.getInstance().takeSnapshot(snapshotController.getConfigurationNode().getUniqueId());
} catch (Exception e) {
ExceptionDetailsErrorDialog.openError(snapshotTableView, Messages.errorGeneric, Messages.takeSnapshotFailed, e);
consumer.accept(null);
return;
}
countDownLatch.await();
completion.accept(Arrays.asList(snapshotEntries));
executorService.shutdown();
// Service can only return nulls for disconnected PVs, but UI expects VDisonnectedData
snapshotItems.forEach(si -> {
if (si.getValue() == null) {
si.setValue(VDisconnectedData.INSTANCE);
}
if (si.getReadbackValue() == null) {
si.setReadbackValue(VDisconnectedData.INSTANCE);
}
});
Snapshot snapshot = new Snapshot();
snapshot.setSnapshotNode(Node.builder().nodeType(NodeType.SNAPSHOT).build());
SnapshotData snapshotData = new SnapshotData();
snapshotData.setSnapshotItems(snapshotItems);
snapshot.setSnapshotData(snapshotData);
showSnapshotInTable(snapshot);
if (!Preferences.default_snapshot_name_date_format.isEmpty()) {
SimpleDateFormat formatter = new SimpleDateFormat(Preferences.default_snapshot_name_date_format);
snapshot.getSnapshotNode().setName(formatter.format(new Date()));
}
consumer.accept(snapshot);
});

}

public void updateThreshold(Snapshot snapshot, double threshold) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ tagCommentLabel=Comment
tagRemoveConfirmationTitle=Remove Tag
tagRemoveConfirmationContent=Are you sure to remove the tag on the selected snapshot(s)?
takeSnapshot=Take Snapshot
takeSnapshotFailed=Failed to take snapshot
timestamp=Timestamp
Time=Time
StartTime=Start Time
Expand Down
Loading

0 comments on commit 74bded8

Please sign in to comment.