The original issue #602, where support for continuations was developed, did not envisage situations where a context in which the request for "more data", expressed by throwing exception NeedMoreDate, may not be satisfiable. In practice such situations do occur and need to be handled ad hoc for each specific case. However, due to the ease with which NeedMoreDate can be introduced, potentially breaking an application in many places, demands a systemic approach that would:
Provide a way for a caller to notify a callee that "more data" can be satisfied.
Provide a way for a callee to check whether "more data" can be satisfied in a given context before throwing NeedMoreData.
This is not an automagical solution where context that support "more data" can be identified automatically. Instead, additional API needs to be developed that would need to be used explicitly when developing with continuations. With the sensible defaults this should not introduce too much overhead, but would give more control to developers over the situation.
It should be sufficient to provide 2 methods as part of CommonEntityDao:
[x] 1. co.setContinuationSuported(boolean) to instructs a companion instance of whether the context of its invocation is such that can satisfy requests for "more data".
[x] 2. co.isContinuationSupported(): boolean for a companion to check before throwing NeedMoreData of whether the context in which a companion is used can handle such exception and can provide the requested data.
So far, there are 2 practical contexts in which "more data" can be provided:
Direct saving of entities from their masters, which is equivalent to calling co.save(entity) on entity companions, but invoked from a web service layer.
This is a context in which co.setContinuationSuported(true) can be used by default in EntityResourceContinuationsHelper.saveWithContinuations before invoking co.save(entity). In other words, "more data" is always satisfiable for entities that are being saved directly from their master.
Invocation of co.save(entity) in tests that need to test the "more data" explicitly.
This is a context where developers can catch NeedMoreData and assigned "more data" as expected by their tests.
All other current cases, which means invocations of co.save() in the context of other co.save for other companions cannot satisfy "more data". Therefore, companion instances should defensively consider that continuations are not supported by default because a context of their execution is not known ahead of time. And so, a typical use case should now look like this:
// if more data can be provided, but was not yet provided -- request it
if (isContinuationSupported() && !moreData("keyForMyData").isPresent()) {
throw new NeedMoreData("My data is needed.", MyData.class, "keyForMyData");
}
// otherwise, if more data is present then use it
else if (moreData("keyForMyData").isPresent()) {
final MyData data = this.<MyData> moreData("keyForMyData").get();
// do something with data
}
However, there can be situations where "more data" is required and saving should not succeed without that data. In such cases simply don't check support for continuations and request "more data" regardless.
// if more data is not yet provided -- request it
if (!moreData("keyForMyData").isPresent()) {
throw new NeedMoreData("My data is needed.", MyData.class, "keyForMyData");
}
// otherwise, more data is present and it can be used
else {
final MyData data = this.<MyData> moreData("keyForMyData").get();
// do something with data
}
Expected outcome
Improved safety of using continuations for "more data" with control over contexts in which "more data" can or cannot be satisfied.
Description
The original issue #602, where support for continuations was developed, did not envisage situations where a context in which the request for "more data", expressed by throwing exception
NeedMoreDate
, may not be satisfiable. In practice such situations do occur and need to be handled ad hoc for each specific case. However, due to the ease with whichNeedMoreDate
can be introduced, potentially breaking an application in many places, demands a systemic approach that would:NeedMoreData
.This is not an automagical solution where context that support "more data" can be identified automatically. Instead, additional API needs to be developed that would need to be used explicitly when developing with continuations. With the sensible defaults this should not introduce too much overhead, but would give more control to developers over the situation.
It should be sufficient to provide 2 methods as part of
CommonEntityDao
:[x] 1.
co.setContinuationSuported(boolean)
to instructs a companion instance of whether the context of its invocation is such that can satisfy requests for "more data".[x] 2.
co.isContinuationSupported(): boolean
for a companion to check before throwingNeedMoreData
of whether the context in which a companion is used can handle such exception and can provide the requested data.So far, there are 2 practical contexts in which "more data" can be provided:
Direct saving of entities from their masters, which is equivalent to calling
co.save(entity)
on entity companions, but invoked from a web service layer.This is a context in which
co.setContinuationSuported(true)
can be used by default inEntityResourceContinuationsHelper.saveWithContinuations
before invokingco.save(entity)
. In other words, "more data" is always satisfiable for entities that are being saved directly from their master.Invocation of
co.save(entity)
in tests that need to test the "more data" explicitly.This is a context where developers can catch
NeedMoreData
and assigned "more data" as expected by their tests.All other current cases, which means invocations of
co.save()
in the context of otherco.save
for other companions cannot satisfy "more data". Therefore, companion instances should defensively consider that continuations are not supported by default because a context of their execution is not known ahead of time. And so, a typical use case should now look like this:However, there can be situations where "more data" is required and saving should not succeed without that data. In such cases simply don't check support for continuations and request "more data" regardless.
Expected outcome
Improved safety of using continuations for "more data" with control over contexts in which "more data" can or cannot be satisfied.