Commit 41feb767 authored by Kenton Varda's avatar Kenton Varda

More RPC protocol WIP.

parent 966d25a2
......@@ -110,7 +110,7 @@ public:
}
return response->message.getRoot();
}
void allowAsyncCancellation(bool allow) override {
void allowAsyncCancellation() override {
// ignored for local calls
}
bool isCanceled() override {
......
......@@ -178,6 +178,8 @@ class CallContext: public kj::DisallowConstCopy {
//
// Methods of this class may only be called from within the server's event loop, not from other
// threads.
//
// The CallContext becomes invalid as soon as the call reports completion.
public:
explicit CallContext(CallContextHook& hook);
......@@ -205,7 +207,7 @@ public:
// `firstSegmentWordSize` indicates the suggested size of the message's first segment. This
// is a hint only. If not specified, the system will decide on its own.
void allowAsyncCancellation(bool allow = true);
void allowAsyncCancellation();
// Indicate that it is OK for the RPC system to discard its Promise for this call's result if
// the caller cancels the call, thereby transitively canceling any asynchronous operations the
// call implementation was performing. This is not done by default because it could represent a
......@@ -213,8 +215,6 @@ public:
// a bad state if an operation is canceled at an arbitrary point. However, for long-running
// method calls that hold significant resources, prompt cancellation is often useful.
//
// You can also switch back to disallowing cancellation by passing `false` as the argument.
//
// Keep in mind that asynchronous cancellation cannot occur while the method is synchronously
// executing on a local thread. The method must perform an asynchronous operation or call
// `EventLoop::current().runLater()` to yield control.
......@@ -340,7 +340,7 @@ public:
virtual ObjectPointer::Reader getParams() = 0;
virtual void releaseParams() = 0;
virtual ObjectPointer::Builder getResults(uint firstSegmentWordSize) = 0;
virtual void allowAsyncCancellation(bool allow) = 0;
virtual void allowAsyncCancellation() = 0;
virtual bool isCanceled() = 0;
virtual kj::Own<CallContextHook> addRef() = 0;
......@@ -551,8 +551,8 @@ inline Orphanage CallContext<Params, Results>::getResultsOrphanage(uint firstSeg
return Orphanage::getForMessageContaining(hook->getResults(firstSegmentWordSize));
}
template <typename Params, typename Results>
inline void CallContext<Params, Results>::allowAsyncCancellation(bool allow) {
hook->allowAsyncCancellation(allow);
inline void CallContext<Params, Results>::allowAsyncCancellation() {
hook->allowAsyncCancellation();
}
template <typename Params, typename Results>
inline bool CallContext<Params, Results>::isCanceled() {
......
......@@ -534,7 +534,7 @@ public:
void setResults(DynamicStruct::Reader value);
void adoptResults(Orphan<DynamicStruct>&& value);
Orphanage getResultsOrphanage(uint firstSegmentWordSize = 0);
void allowAsyncCancellation(bool allow = true);
void allowAsyncCancellation();
bool isCanceled();
private:
......@@ -1513,8 +1513,8 @@ inline Orphanage CallContext<DynamicStruct, DynamicStruct>::getResultsOrphanage(
uint firstSegmentWordSize) {
return Orphanage::getForMessageContaining(hook->getResults(firstSegmentWordSize));
}
inline void CallContext<DynamicStruct, DynamicStruct>::allowAsyncCancellation(bool allow) {
hook->allowAsyncCancellation(allow);
inline void CallContext<DynamicStruct, DynamicStruct>::allowAsyncCancellation() {
hook->allowAsyncCancellation();
}
inline bool CallContext<DynamicStruct, DynamicStruct>::isCanceled() {
return hook->isCanceled();
......
......@@ -232,6 +232,9 @@ struct ObjectPointer {
kj::Own<const ClientHook> asCap() const;
// Expect that the result is a capability and construct a pipelined version of it now.
inline kj::Own<const PipelineHook> releasePipelineHook() { return kj::mv(hook); }
// For use by RPC implementations.
private:
kj::Own<const PipelineHook> hook;
kj::Array<PipelineOp> ops;
......
This diff is collapsed.
......@@ -746,16 +746,19 @@ struct Exception {
# automated bug report were to be generated for this error, should it be initially filed on the
# caller's code or the callee's? This is a guess. Generally guesses should err towards blaming
# the callee -- at the very least, the callee should be on the hook for improving their error
# handling to be more confident.
# handling to be more confident in assigning blame.
isPermanent @2 :Bool;
durability @2 :Durability;
# In the best estimate of the error source, is this error likely to repeat if the same call is
# executed again? Callers might use this to decide when to retry a request.
isOverloaded @3 :Bool;
# In the best estimate of the error source, is it likely this error was caused by the system
# being overloaded? If so, the caller probably should not retry the request now, but may
# consider retrying it later.
enum Durability {
permanent @0; # Retrying the exact same operation will fail in the same way.
temporary @1; # Retrying the exact same operation might succeed.
overloaded @2; # The error may be due to the system being overloaded. Retrying may work
# later on, but for now the caller should not retry right away as this will
# likely exacerbate the problem.
}
}
# ========================================================================================
......
......@@ -639,7 +639,7 @@ class ForkedPromise {
// Like `Promise<T>`, this is a pass-by-move type.
public:
inline ForkedPromise(decltype(nullptr)): hub(nullptr) {}
inline ForkedPromise(decltype(nullptr)) {}
Promise<_::Forked<T>> addBranch() const;
// Add a new branch to the fork. The branch is equivalent to the original promise, except
......
......@@ -131,8 +131,9 @@ ArrayPtr<const char> KJ_STRINGIFY(Exception::Nature nature) {
ArrayPtr<const char> KJ_STRINGIFY(Exception::Durability durability) {
static const char* DURABILITY_STRINGS[] = {
"permanent",
"temporary",
"permanent"
"overloaded"
};
const char* s = DURABILITY_STRINGS[static_cast<uint>(durability)];
......
......@@ -61,8 +61,11 @@ public:
};
enum class Durability {
PERMANENT, // Retrying the exact same operation will fail in exactly the same way.
TEMPORARY, // Retrying the exact same operation might succeed.
PERMANENT // Retrying the exact same operation will fail in exactly the same way.
OVERLOADED // The error was possibly caused by the system being overloaded. Retrying the
// operation might work at a later point in time, but the caller should NOT retry
// immediately as this will probably exacerbate the problem.
// Make sure to update the stringifier if you add a new durability.
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment