forked from j62/ctbrec
1
0
Fork 0

Implement recording priorities for RemoteRecorder

This commit is contained in:
0xboobface 2020-01-04 15:30:54 +01:00
parent 5448763b9d
commit d82c3b490b
5 changed files with 82 additions and 39 deletions

View File

@ -174,7 +174,7 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
priority.setPrefWidth(90); priority.setPrefWidth(90);
priority.setEditable(true); priority.setEditable(true);
priority.setOnEditStart(e -> cellEditing = true); priority.setOnEditStart(e -> cellEditing = true);
priority.setOnEditCommit(this::updatePriority); priority.setOnEditCommit(this::onUpdatePriority);
priority.setOnEditCancel(e -> cellEditing = false); priority.setOnEditCancel(e -> cellEditing = false);
TableColumn<JavaFxModel, String> notes = new TableColumn<>("Notes"); TableColumn<JavaFxModel, String> notes = new TableColumn<>("Notes");
notes.setCellValueFactory(cdf -> { notes.setCellValueFactory(cdf -> {
@ -277,26 +277,31 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
restoreState(); restoreState();
} }
private void updatePriority(CellEditEvent<JavaFxModel, Number> evt) { private void onUpdatePriority(CellEditEvent<JavaFxModel, Number> evt) {
try { try {
int prio = Optional.ofNullable(evt.getNewValue()).map(Number::intValue).orElse(-1); int prio = Optional.ofNullable(evt.getNewValue()).map(Number::intValue).orElse(-1);
if (prio < 0 || prio > 100) { JavaFxModel m = evt.getRowValue();
String msg = "Priority has to be between 0 and 100"; updatePriority(m, prio);
Dialogs.showError(table.getScene(), "Invalid value", msg, null);
} else {
evt.getRowValue().setPriority(prio);
try {
Config.getInstance().save();
} catch (IOException e) {
LOG.warn("Couldn't save updated priority value {} for {} - {}", evt.getNewValue(), evt.getRowValue().getName(), e.getMessage());
}
}
table.refresh(); table.refresh();
} finally { } finally {
cellEditing = false; cellEditing = false;
} }
} }
private void updatePriority(JavaFxModel model, int priority) {
try {
if (priority < 0 || priority > 100) {
String msg = "Priority has to be between 0 and 100";
Dialogs.showError(table.getScene(), "Invalid value", msg, null);
} else {
model.setPriority(priority);
recorder.priorityChanged(model.getDelegate());
}
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
Dialogs.showError(table.getScene(), "Couldn't update priority", e.getMessage(), e);
}
}
private void addModel(ActionEvent e) { private void addModel(ActionEvent e) {
String input = model.getText(); String input = model.getText();
if (StringUtil.isBlank(input)) { if (StringUtil.isBlank(input)) {
@ -735,11 +740,7 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
} }
prio = Math.min(Math.max(0, prio), 100); prio = Math.min(Math.max(0, prio), 100);
m.setPriority(prio); m.setPriority(prio);
try { updatePriority(m, prio);
Config.getInstance().save();
} catch (IOException e) {
LOG.warn("Couldn't save updated priority value {} for {} - {}", prio, m.getName(), e.getMessage());
}
} }
}); });

View File

@ -657,4 +657,23 @@ public class NextGenLocalRecorder implements Recorder {
} }
LOG.error("Recording {} not found. Can't rerun post-processing", recording); LOG.error("Recording {} not found. Can't rerun post-processing", recording);
} }
@Override
public void priorityChanged(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException {
recorderLock.lock();
try {
if (models.contains(model)) {
int index = models.indexOf(model);
models.get(index).setPriority(model.getPriority());
config.save();
} else {
LOG.warn("Couldn't change priority for model {}. Not found in list", model.getName());
return;
}
} catch (IOException e) {
LOG.error("Couldn't save config", e);
} finally {
recorderLock.unlock();
}
}
} }

View File

@ -11,11 +11,11 @@ import ctbrec.Recording;
import ctbrec.io.HttpClient; import ctbrec.io.HttpClient;
public interface Recorder { public interface Recorder {
public void startRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException; public void startRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
public void stopRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException; public void stopRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
public void switchStreamSource(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException; public void switchStreamSource(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
/** /**
* Returns true, if a model is in the list of models to record. This does not reflect, if there currently is a recording running. The model might be offline * Returns true, if a model is in the list of models to record. This does not reflect, if there currently is a recording running. The model might be offline
@ -30,14 +30,14 @@ public interface Recorder {
*/ */
public List<Model> getModels(); public List<Model> getModels();
public List<Recording> getRecordings() throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException; public List<Recording> getRecordings() throws IOException, InvalidKeyException, NoSuchAlgorithmException;
public void delete(Recording recording) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException; public void delete(Recording recording) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
public void shutdown(); public void shutdown();
public void suspendRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException; public void suspendRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
public void resumeRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException; public void resumeRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
public boolean isSuspended(Model model); public boolean isSuspended(Model model);
@ -55,7 +55,7 @@ public interface Recorder {
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
* @throws InvalidKeyException * @throws InvalidKeyException
*/ */
public default List<Model> getCurrentlyRecording() throws InvalidKeyException, NoSuchAlgorithmException, IllegalStateException, IOException { public default List<Model> getCurrentlyRecording() throws InvalidKeyException, NoSuchAlgorithmException, IOException {
List<Recording> recordings = getRecordings(); List<Recording> recordings = getRecordings();
return getModels().stream().filter(m -> { return getModels().stream().filter(m -> {
for (Recording recording : recordings) { for (Recording recording : recordings) {
@ -92,5 +92,15 @@ public interface Recorder {
* @throws InvalidKeyException * @throws InvalidKeyException
* @throws IOException * @throws IOException
*/ */
public void rerunPostProcessing(Recording recording) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException; public void rerunPostProcessing(Recording recording) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
/**
* Tells the recorder, that the recrodng priority for the given model has changed
*
* @param model the model with changed priority. The new value can be retrieved with {@link Model#getPriority()}
* @throws IOException
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
*/
public void priorityChanged(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
} }

View File

@ -138,7 +138,7 @@ public class RemoteRecorder implements Recorder {
@Override @Override
public List<Model> getModels() { public List<Model> getModels() {
if (!lastSync.equals(Instant.EPOCH) && lastSync.isBefore(Instant.now().minusSeconds(60))) { if (!lastSync.equals(Instant.EPOCH) && lastSync.isBefore(Instant.now().minusSeconds(60))) {
throw new RuntimeException("Last sync was over a minute ago"); throw new IllegalStateException("Last sync was over a minute ago");
} }
return new ArrayList<>(models); return new ArrayList<>(models);
} }
@ -149,6 +149,9 @@ public class RemoteRecorder implements Recorder {
} }
private class SyncThread extends Thread { private class SyncThread extends Thread {
private static final String SERVER_RETURNED_ERROR = "Server returned error: {} - {}";
private static final String COULDNT_SYNCHRONIZE_WITH_SERVER = "Couldn't synchronize with server";
private static final String COULDNT_SYNCHRONIZE_WITH_SERVER_HTTP_STATUS = "Couldn't synchronize with server. HTTP status: {} - {}";
private volatile boolean running = false; private volatile boolean running = false;
public SyncThread() { public SyncThread() {
@ -182,11 +185,11 @@ public class RemoteRecorder implements Recorder {
spaceTotal = resp.getLong("spaceTotal"); spaceTotal = resp.getLong("spaceTotal");
spaceFree = resp.getLong("spaceFree"); spaceFree = resp.getLong("spaceFree");
} else { } else {
LOG.error("Couldn't synchronize with server. HTTP status: {} - {}", response.code(), json); LOG.error(COULDNT_SYNCHRONIZE_WITH_SERVER_HTTP_STATUS, response.code(), json);
} }
} }
} catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e) { } catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e) {
LOG.error("Couldn't synchronize with server", e); LOG.error(COULDNT_SYNCHRONIZE_WITH_SERVER, e);
} }
} }
@ -212,14 +215,14 @@ public class RemoteRecorder implements Recorder {
} }
lastSync = Instant.now(); lastSync = Instant.now();
} else { } else {
LOG.error("Server returned error: {} - {}", resp.status, resp.msg); LOG.error(SERVER_RETURNED_ERROR, resp.status, resp.msg);
} }
} else { } else {
LOG.error("Couldn't synchronize with server. HTTP status: {} - {}", response.code(), json); LOG.error(COULDNT_SYNCHRONIZE_WITH_SERVER_HTTP_STATUS, response.code(), json);
} }
} }
} catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e) { } catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e) {
LOG.error("Couldn't synchronize with server", e); LOG.error(COULDNT_SYNCHRONIZE_WITH_SERVER, e);
} }
} }
@ -244,14 +247,14 @@ public class RemoteRecorder implements Recorder {
} }
} }
} else { } else {
LOG.error("Server returned error: {} - {}", resp.status, resp.msg); LOG.error(SERVER_RETURNED_ERROR, resp.status, resp.msg);
} }
} else { } else {
LOG.error("Couldn't synchronize with server. HTTP status: {} - {}", response.code(), json); LOG.error(COULDNT_SYNCHRONIZE_WITH_SERVER_HTTP_STATUS, response.code(), json);
} }
} }
} catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e) { } catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e) {
LOG.error("Couldn't synchronize with server", e); LOG.error(COULDNT_SYNCHRONIZE_WITH_SERVER, e);
} }
} }
@ -284,14 +287,14 @@ public class RemoteRecorder implements Recorder {
} }
recordings = newRecordings; recordings = newRecordings;
} else { } else {
LOG.error("Server returned error: {} - {}", resp.status, resp.msg); LOG.error(SERVER_RETURNED_ERROR, resp.status, resp.msg);
} }
} else { } else {
LOG.error("Couldn't synchronize with server. HTTP status: {} - {}", response.code(), json); LOG.error(COULDNT_SYNCHRONIZE_WITH_SERVER_HTTP_STATUS, response.code(), json);
} }
} }
} catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e) { } catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e) {
LOG.error("Couldn't synchronize with server", e); LOG.error(COULDNT_SYNCHRONIZE_WITH_SERVER, e);
} }
} }
@ -479,4 +482,9 @@ public class RemoteRecorder implements Recorder {
} }
} }
} }
@Override
public void priorityChanged(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException {
sendRequest("changePriority", model);
}
} }

View File

@ -168,6 +168,11 @@ public class RecorderServlet extends AbstractCtbrecServlet {
response = "{\"status\": \"success\", \"spaceTotal\": "+recorder.getTotalSpaceBytes()+", \"spaceFree\": "+recorder.getFreeSpaceBytes()+"}"; response = "{\"status\": \"success\", \"spaceTotal\": "+recorder.getTotalSpaceBytes()+", \"spaceFree\": "+recorder.getFreeSpaceBytes()+"}";
resp.getWriter().write(response); resp.getWriter().write(response);
break; break;
case "changePriority":
recorder.priorityChanged(request.model);
response = "{\"status\": \"success\"}";
resp.getWriter().write(response);
break;
default: default:
resp.setStatus(SC_BAD_REQUEST); resp.setStatus(SC_BAD_REQUEST);
response = "{\"status\": \"error\", \"msg\": \"Unknown action ["+request.action+"]\"}"; response = "{\"status\": \"error\", \"msg\": \"Unknown action ["+request.action+"]\"}";