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

More RPC protocol WIP.

parent 966d25a2
...@@ -110,7 +110,7 @@ public: ...@@ -110,7 +110,7 @@ public:
} }
return response->message.getRoot(); return response->message.getRoot();
} }
void allowAsyncCancellation(bool allow) override { void allowAsyncCancellation() override {
// ignored for local calls // ignored for local calls
} }
bool isCanceled() override { bool isCanceled() override {
......
...@@ -178,6 +178,8 @@ class CallContext: public kj::DisallowConstCopy { ...@@ -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 // Methods of this class may only be called from within the server's event loop, not from other
// threads. // threads.
//
// The CallContext becomes invalid as soon as the call reports completion.
public: public:
explicit CallContext(CallContextHook& hook); explicit CallContext(CallContextHook& hook);
...@@ -205,7 +207,7 @@ public: ...@@ -205,7 +207,7 @@ public:
// `firstSegmentWordSize` indicates the suggested size of the message's first segment. This // `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. // 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 // 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 // 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 // call implementation was performing. This is not done by default because it could represent a
...@@ -213,8 +215,6 @@ public: ...@@ -213,8 +215,6 @@ public:
// a bad state if an operation is canceled at an arbitrary point. However, for long-running // 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. // 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 // 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 // executing on a local thread. The method must perform an asynchronous operation or call
// `EventLoop::current().runLater()` to yield control. // `EventLoop::current().runLater()` to yield control.
...@@ -340,7 +340,7 @@ public: ...@@ -340,7 +340,7 @@ public:
virtual ObjectPointer::Reader getParams() = 0; virtual ObjectPointer::Reader getParams() = 0;
virtual void releaseParams() = 0; virtual void releaseParams() = 0;
virtual ObjectPointer::Builder getResults(uint firstSegmentWordSize) = 0; virtual ObjectPointer::Builder getResults(uint firstSegmentWordSize) = 0;
virtual void allowAsyncCancellation(bool allow) = 0; virtual void allowAsyncCancellation() = 0;
virtual bool isCanceled() = 0; virtual bool isCanceled() = 0;
virtual kj::Own<CallContextHook> addRef() = 0; virtual kj::Own<CallContextHook> addRef() = 0;
...@@ -551,8 +551,8 @@ inline Orphanage CallContext<Params, Results>::getResultsOrphanage(uint firstSeg ...@@ -551,8 +551,8 @@ inline Orphanage CallContext<Params, Results>::getResultsOrphanage(uint firstSeg
return Orphanage::getForMessageContaining(hook->getResults(firstSegmentWordSize)); return Orphanage::getForMessageContaining(hook->getResults(firstSegmentWordSize));
} }
template <typename Params, typename Results> template <typename Params, typename Results>
inline void CallContext<Params, Results>::allowAsyncCancellation(bool allow) { inline void CallContext<Params, Results>::allowAsyncCancellation() {
hook->allowAsyncCancellation(allow); hook->allowAsyncCancellation();
} }
template <typename Params, typename Results> template <typename Params, typename Results>
inline bool CallContext<Params, Results>::isCanceled() { inline bool CallContext<Params, Results>::isCanceled() {
......
...@@ -534,7 +534,7 @@ public: ...@@ -534,7 +534,7 @@ public:
void setResults(DynamicStruct::Reader value); void setResults(DynamicStruct::Reader value);
void adoptResults(Orphan<DynamicStruct>&& value); void adoptResults(Orphan<DynamicStruct>&& value);
Orphanage getResultsOrphanage(uint firstSegmentWordSize = 0); Orphanage getResultsOrphanage(uint firstSegmentWordSize = 0);
void allowAsyncCancellation(bool allow = true); void allowAsyncCancellation();
bool isCanceled(); bool isCanceled();
private: private:
...@@ -1513,8 +1513,8 @@ inline Orphanage CallContext<DynamicStruct, DynamicStruct>::getResultsOrphanage( ...@@ -1513,8 +1513,8 @@ inline Orphanage CallContext<DynamicStruct, DynamicStruct>::getResultsOrphanage(
uint firstSegmentWordSize) { uint firstSegmentWordSize) {
return Orphanage::getForMessageContaining(hook->getResults(firstSegmentWordSize)); return Orphanage::getForMessageContaining(hook->getResults(firstSegmentWordSize));
} }
inline void CallContext<DynamicStruct, DynamicStruct>::allowAsyncCancellation(bool allow) { inline void CallContext<DynamicStruct, DynamicStruct>::allowAsyncCancellation() {
hook->allowAsyncCancellation(allow); hook->allowAsyncCancellation();
} }
inline bool CallContext<DynamicStruct, DynamicStruct>::isCanceled() { inline bool CallContext<DynamicStruct, DynamicStruct>::isCanceled() {
return hook->isCanceled(); return hook->isCanceled();
......
...@@ -232,6 +232,9 @@ struct ObjectPointer { ...@@ -232,6 +232,9 @@ struct ObjectPointer {
kj::Own<const ClientHook> asCap() const; kj::Own<const ClientHook> asCap() const;
// Expect that the result is a capability and construct a pipelined version of it now. // 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: private:
kj::Own<const PipelineHook> hook; kj::Own<const PipelineHook> hook;
kj::Array<PipelineOp> ops; kj::Array<PipelineOp> ops;
......
This diff is collapsed.
...@@ -746,16 +746,19 @@ struct Exception { ...@@ -746,16 +746,19 @@ struct Exception {
# automated bug report were to be generated for this error, should it be initially filed on the # 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 # 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 # 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 # 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. # executed again? Callers might use this to decide when to retry a request.
isOverloaded @3 :Bool; enum Durability {
# In the best estimate of the error source, is it likely this error was caused by the system permanent @0; # Retrying the exact same operation will fail in the same way.
# being overloaded? If so, the caller probably should not retry the request now, but may temporary @1; # Retrying the exact same operation might succeed.
# consider retrying it later. 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 { ...@@ -639,7 +639,7 @@ class ForkedPromise {
// Like `Promise<T>`, this is a pass-by-move type. // Like `Promise<T>`, this is a pass-by-move type.
public: public:
inline ForkedPromise(decltype(nullptr)): hub(nullptr) {} inline ForkedPromise(decltype(nullptr)) {}
Promise<_::Forked<T>> addBranch() const; Promise<_::Forked<T>> addBranch() const;
// Add a new branch to the fork. The branch is equivalent to the original promise, except // 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) { ...@@ -131,8 +131,9 @@ ArrayPtr<const char> KJ_STRINGIFY(Exception::Nature nature) {
ArrayPtr<const char> KJ_STRINGIFY(Exception::Durability durability) { ArrayPtr<const char> KJ_STRINGIFY(Exception::Durability durability) {
static const char* DURABILITY_STRINGS[] = { static const char* DURABILITY_STRINGS[] = {
"permanent",
"temporary", "temporary",
"permanent" "overloaded"
}; };
const char* s = DURABILITY_STRINGS[static_cast<uint>(durability)]; const char* s = DURABILITY_STRINGS[static_cast<uint>(durability)];
......
...@@ -61,8 +61,11 @@ public: ...@@ -61,8 +61,11 @@ public:
}; };
enum class Durability { enum class Durability {
PERMANENT, // Retrying the exact same operation will fail in exactly the same way.
TEMPORARY, // Retrying the exact same operation might succeed. 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. // 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