capnproto

FORK: Cap'n Proto serialization/RPC system - core tools and C++ library
git clone https://git.neptards.moe/neptards/capnproto.git
Log | Files | Refs | README | LICENSE

reconnect.h (3712B)


      1 // Copyright (c) 2020 Cloudflare, Inc. and contributors
      2 // Licensed under the MIT License:
      3 //
      4 // Permission is hereby granted, free of charge, to any person obtaining a copy
      5 // of this software and associated documentation files (the "Software"), to deal
      6 // in the Software without restriction, including without limitation the rights
      7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      8 // copies of the Software, and to permit persons to whom the Software is
      9 // furnished to do so, subject to the following conditions:
     10 //
     11 // The above copyright notice and this permission notice shall be included in
     12 // all copies or substantial portions of the Software.
     13 //
     14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     20 // THE SOFTWARE.
     21 
     22 #pragma once
     23 
     24 #include "capability.h"
     25 #include <kj/function.h>
     26 
     27 CAPNP_BEGIN_HEADER
     28 
     29 namespace capnp {
     30 
     31 template <typename ConnectFunc>
     32 auto autoReconnect(ConnectFunc&& connect);
     33 // Creates a capability that reconstructs itself every time it becomes disconnected.
     34 //
     35 // `connect()` is a function which is invoked to initially construct the capability, and then
     36 // invoked again each time the capability is found to be disconnected. `connect()` may return
     37 // any capability `Client` type.
     38 //
     39 // Example usage might look like:
     40 //
     41 //     Foo::Client foo = autoReconnect([&rpcSystem, vatId]() {
     42 //       return rpcSystem.bootstrap(vatId).castAs<RootType>().getFooRequest().send().getFoo();
     43 //     });
     44 //
     45 // The given function is initially called synchronously, and the returned `foo` is a wrapper
     46 // around what the function returned. But any time this capability becomes disconnected, the
     47 // function is invoked again, and future calls are directed to the new result.
     48 //
     49 // Any call that is in-flight when the capability becomes disconnected still fails with a
     50 // DISCONNECTED exception. The caller should respond by retrying, as a retry will target the
     51 // newly-reconnected capability. However, the caller should limit the number of times it retries,
     52 // to avoid an infinite loop in the case that the DISCONNECTED exception actually represents a
     53 // permanent problem. Consider using `kj::retryOnDisconnect()` to implement this behavior.
     54 
     55 template <typename ConnectFunc>
     56 auto lazyAutoReconnect(ConnectFunc&& connect);
     57 // The same as autoReconnect, but doesn't call the provided connect function until the first
     58 // time the capability is used. Note that only the initial connection is lazy -- upon
     59 // disconnected errors this will still reconnect eagerly.
     60 
     61 // =======================================================================================
     62 // inline implementation details
     63 
     64 Capability::Client autoReconnect(kj::Function<Capability::Client()> connect);
     65 template <typename ConnectFunc>
     66 auto autoReconnect(ConnectFunc&& connect) {
     67   return autoReconnect(kj::Function<Capability::Client()>(kj::fwd<ConnectFunc>(connect)))
     68       .castAs<FromClient<kj::Decay<decltype(connect())>>>();
     69 }
     70 
     71 Capability::Client lazyAutoReconnect(kj::Function<Capability::Client()> connect);
     72 template <typename ConnectFunc>
     73 auto lazyAutoReconnect(ConnectFunc&& connect) {
     74   return lazyAutoReconnect(kj::Function<Capability::Client()>(kj::fwd<ConnectFunc>(connect)))
     75       .castAs<FromClient<kj::Decay<decltype(connect())>>>();
     76 }
     77 
     78 }  // namespace capnp
     79 
     80 CAPNP_END_HEADER