Wednesday, November 27, 2013

Re: Re-firing a failed/rejected server call in RequestFactory, is this possible?

Jan and I further looked into the issue and actually found a working solution that is "less hacky" than Eric's.

private void setupRequest(UserRequest request, UserProxy proxy) {
final UserProxy editableProxy = request.edit(proxy);
editorDriver.edit(editableProxy, request);
request.save(editableProxy).to(new Receiver<T>() {

@Override
public void onFailure(ServerFailure error) {
...
setupRequest(getRequest(), editableProxy);
}

@Override
public void onConstraintViolation(
        ...
}

@Override
public void onSuccess(T response) {
...
}

});
}

This keeps the data around and allows "re-firing" the request.

The explicit request.edit() is necessary because otherwise the entered data is lost when another failure occurs.

Am Dienstag, 26. November 2013 18:33:22 UTC+1 schrieb Thomas Broyer:
I don't disagree. A non-reachable database is likely to trigger a "global failure" though (in steps 1 or 4 from my previous message), that, IIRC should make the RequestContext "reusable" (it does in some cases, I just can't remember which ones)
That said, you could also handle the error on the server-side and replay the request yourself (and I'm not saying it's easy!)

On Tuesday, November 26, 2013 4:59:38 PM UTC+1, Jan Marten wrote:
Thank you for clarifying the behavior.

Nevertheless, in my opinion there is a use-case where the data should be reusable after a server failure.

SQL exceptions like a unique constraint violation could be checked before sending the request but 
there might be server failures like a non-reachable database which is unpredictable.

When something like this happens one could prompt the user to retry after a few minutes.
But since the request cannot be reused the user cannot resend it's entered data.

Am Dienstag, 26. November 2013 16:25:06 UTC+1 schrieb Thomas Broyer:


On Tuesday, November 26, 2013 4:10:08 PM UTC+1, Jan Marten wrote:
The inconsistency with the current RequestFactory is that if in a batch request, a single sub-request has a constraint violation

There's no inconsistency, because that's not how things work.

  1. All objects (entities and "value objects") are "deserialized" from the request (for entities, it involves first retrieving them from the data store)
  2. Then they're all validated. If there's a constraint violation, things stop here and you'll have onConstraintViolations on the client-side, in each and every Receiver attached to the RequestContext (i.e. or one of its Requests/InstanceRequests)
  3. Otherwise, "invocations" are processed, in the same order they were added to the RequestContext on client side. Each invocation either succeeds or fails, and the onSuccess or onFailure will be called accordingly on the client side for the corresponding Receiver. The exception raised might be a ConstraintViolationException, it doesn't change anything: onFailure (not onConstraintViolation) will be called for the appropriate Receiver (not all receivers)
  4. Then all entities (including those returned by "invocations") are checked for "liveness", to tell the client which kind of EntityProxyChange event to fire (PERSIST/UPDATE/DELETE)
  5. And finally the response is constructed, with serialized objects, etc.
 
then onConstraintViolation is called for every sub-request and the whole batch request fails (onFailure is called).
Whereas if in a sub-request an exception is raised on the server only for this single sub-request onFailure is called and the surrounding
batch-request succeeds with onSuccess.

 
Thus, the RequestContext cannot be reused since "reuse" is only called for constraint violations and failures.

Hence, as described in the original post, after a server failure the proxy cannot be reused and the user-entered data is gone (in contrast to a constraint violation).

Yes. Exceptions are meant to be "exceptional", you should use a "return value" to convey errors. In other words, onFailure should never be called, unless something unpredictable happens.

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at http://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/groups/opt_out.

No comments:

Post a Comment