I'm in the process of converting a native Java app to GWT. Communication with the server only happens during state changes, and up to now has been handled by blocking operations.
e.g. Current sync logic:
void onUserClickedSync() {
downloadData(); // blocking operation
uploadData(); // blocking operation
setState(DONE);
}
How can I approach replacing blocking operations with ones which utilise asynchronous callbacks?
My current thinking is to essentially add a bunch of extra "busy" states which don't do anything. I'll then use the callback from the RPC to trigger the next state, where the logic can continue.
e.g. Sync logic would become:
void onUserClickedSync() {
rpc.downloadData(new AsyncCallback<Data> {
public void onSuccess(Data result) {
//...
onDownloaded();
}
//...
});
setState(WAITING_FOR_DOWNLOAD);
}
void onDownloaded() {
rpc.uploadData(new AsyncCallback<Void> {
public void onSuccess(Void void) {
//...
setState(DONE);
}
//...
});
setState(WAITING_FOR_UPLOAD);
}
Is this approach valid? Anything I need to look out for?
EDIT: Rewrote my examples in pseudocode as they were very unclear.
Ok, sorry for pestering you with questions, but the example wasn't really clear to me.
Now that I got a better handle of the situation yes, I think your approach is viable. Just be careful that when the callback changes the state of the system there is no "side effect" that could possibly clash with other events going on at the same time.
Specifically it's not clear if you may be "waiting on multiple callbacks" (i.e. user starts 4 uploads and so you may get 4 callbacks, not necessarily in the "correct order"). Also, is there any chance that the uploaddata method ends before the corresponding downloaddata?
In general you must be careful because while your previous code sacrificed responsiveness for predictability (nothing could happen until the first download finished, for example) now things happen in a more unpredictable order and you may sometimes introduce subtle bugs that would be quite hard to properly diagnose or reproduce.
We don't see the rest of the application, so it's not so clear what else may happen between callbacks, but I urge you to be very careful about that, and also make the callback error handling particularly robust (i.e., what happens if the upload fails midway? do you still get a callback from the server telling you that it aborted? what state you move to then?)