-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How best to handle asynchronous commands? #39
Comments
|
How are you planning to implement the background task in the first place? Which relevant async APIs/libraries are you trying to use? Ultimately no matter how you implement it (EventBus or some other method), just be careful to ensure that any interaction with the Model/LogicManager/Ui should only be done on the JavaFX Application Thread. |
For students who want to pursue this: Just be very aware of threading issues, since Java code can create their own threads at will, as opposed to something like NodeJS which doesn't expose threads to Javascript code and has a single "blessed" event loop that is hidden. I'd highly recommend students who have no prior experience with threading-related issues not to attempt it, especially given the short duration of your project. |
@pyokagan Thanks for your advice! For now I'm planning to use what's provided in After jerry-rigging AB4, I've managed to do some long-running stuff in a Jerry-rigged public CommandResult execute(Model model, CommandHistory history) {
Task<Void> task = new Task<>() { // background task
@Override
public Void call() throws Exception {
Thread.sleep(5000); // some long-running task
Platform.runLater(() -> {
model.addPerson(toAdd);
model.commitAddressBook();
});
return null;
}
};
new Thread(task).start();
return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd)); // does not wait for background task
}
public LogicManager(Model model, Storage storage) {
...
// Set addressBookModified to true whenever the models' address book is modified.
model.getAddressBook().addListener(observable -> addressBookModified = true);
}
@Override
public CommandResult execute(String commandText) {
...
addressBookModified = false;
CommandResult commandResult = command.execute(model, history);
if (addressBookModified) {
storage.saveAddressBook(model.getAddressBook());
}
...
return commandResult;
}
}
private CommandResult executeCommand(String commandText) throws CommandException, ParseException {
...
try {
CommandResult commandResult = logic.execute(commandText);
resultDisplay.setFeedbackSuccessToUser(commandResult.getFeedbackToUser());
return commandResult;
} catch (CommandException | ParseException e) {
resultDisplay.setFeedbackErrorToUser(e.getMessage());
throw e;
}
...
} I guess my question is actually what are some good ways to decouple command execution from storage and UI updates that are not too different from the current design. There are so many possible ways to do it, but not solving it properly could make things really messy fast. |
Unfortunately I can't provide a definite recommendation since concurrent programming is out of CS2103's scope, so it simply isn't considered at all in AB-4. You could try out some designs and let us know how it goes :-) |
In case you actually wanted confirmation:
That sounds about right to me. If a function becomes async, all callers would also need to be rewritten to be async as well. |
I did some digging around and Guava's |
@rlrh go ahead and do it if interested. we won't stop you from learning or trying things 🙂 However, when it comes to counting beans, I am not too sure "taking |
@okkhoy Aha yes counting beans xD I just took a look at the issue about removing |
Sure, do post about your experiences when you are done :-) |
I don't know if I can ask about this, but if it's possible, can I get pointers on how best to handle asynchronous
Command
s?For example, there might be a
Command
that involves fetching data from the Internet, but it should return first to keep theUI
responsive while a background task does the fetching and updates theModel
. However, this isn't possible currently because theLogicManager
only saves theAddressBook
to disk upon command execution, and also theResultDisplay
is only updated upon command execution.There must be many possible ways to go about it, but I'm asking because it looks like there was an
EventsCenter
in the past that would seemingly make all these much easier, but has been removed now. I wonder if this removal is for practical or pedagogical reasons? Would it be better to spend effort reimplementing something likeEventsCenter
to prevent future headache or try to work around the limitations of the current design? Thanks.The text was updated successfully, but these errors were encountered: