aboutsummaryrefslogtreecommitdiffstats
path: root/fnet/src/vespa/fnet/frt/invoker.h
blob: 9483b4305ade863856e7ef7ecfaa936952c5ea1f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#pragma once

#include "rpcrequest.h"
#include <vespa/fnet/task.h>
#include <vespa/fnet/ipackethandler.h>
#include <mutex>
#include <condition_variable>

class FRT_Method;
class FRT_Supervisor;
//-----------------------------------------------------------------------------

class FRT_IRequestWait
{
public:

    /**
     * Destructor.  No cleanup needed for base class.
     */
    virtual ~FRT_IRequestWait(void) {}

    virtual void RequestDone(FRT_RPCRequest *req) = 0;
};

//-----------------------------------------------------------------------------

class FRT_SingleReqWait : public FRT_IRequestWait
{
private:
    std::mutex              _lock;
    std::condition_variable _cond;
    bool            _done;
    bool            _waiting;

public:
    FRT_SingleReqWait();
    virtual ~FRT_SingleReqWait();

    void WaitReq();
    void RequestDone(FRT_RPCRequest *req) override;
};

//-----------------------------------------------------------------------------

class FRT_ITimeoutHandler
{
public:

    /**
     * Destructor.  No cleanup needed for base class.
     */
    virtual ~FRT_ITimeoutHandler() {}

    virtual void HandleTimeout() = 0;
};

//-----------------------------------------------------------------------------

class FRT_RPCInvoker : public FRT_IReturnHandler
{
private:
    FRT_RPCRequest *_req;
    FRT_Method     *_method;
    bool            _noReply;

    FRT_RPCInvoker(const FRT_RPCInvoker &);
    FRT_RPCInvoker &operator=(const FRT_RPCInvoker &);

public:
    FRT_RPCInvoker(FRT_Supervisor *supervisor,
                   FRT_RPCRequest *req,
                   bool noReply);

    void ForceMethod(FRT_Method *method) { _method = method; }

    FRT_RPCRequest *GetRequest() { return _req; }

    void HandleDone(bool freeChannel);
    bool Invoke();
    void HandleReturn() override;
    FNET_Connection *GetConnection() override;
};

//-----------------------------------------------------------------------------

class FRT_HookInvoker : public FRT_IReturnHandler
{
private:
    FRT_RPCRequest  *_req;
    FRT_Method      *_hook;
    FNET_Connection *_conn;

    FRT_HookInvoker(const FRT_HookInvoker &);
    FRT_HookInvoker &operator=(const FRT_HookInvoker &);

public:
    FRT_HookInvoker(FRT_RPCRequest *req,
                    FRT_Method *hook,
                    FNET_Connection *conn)
        : _req(req),
          _hook(hook),
          _conn(conn)
    {
        _req->SetReturnHandler(this);
    }

    void Invoke();
    void HandleReturn() override;
    FNET_Connection *GetConnection() override;
};

//-----------------------------------------------------------------------------

class FRT_RPCAdapter : public FNET_Task,
                       public FRT_IAbortHandler,
                       public FNET_IPacketHandler
{
private:
    FRT_RPCRequest   *_req;
    FRT_IRequestWait *_waiter;
    FNET_Channel     *_channel;

    FRT_RPCAdapter(const FRT_RPCAdapter &);
    FRT_RPCAdapter &operator=(const FRT_RPCAdapter &);

public:
    FRT_RPCAdapter(FNET_Scheduler *scheduler,
                   FRT_RPCRequest *req,
                   FRT_IRequestWait *waiter);

    void SetChannel(FNET_Channel *channel) { _channel = channel; }

    void HandleDone();

    bool HandleAbort() override;
    void PerformTask() override;
    HP_RetCode HandlePacket(FNET_Packet *packet, FNET_Context context) override;
};

//-----------------------------------------------------------------------------

VESPA_CAN_SKIP_DESTRUCTION(FRT_RPCAdapter)
VESPA_CAN_SKIP_DESTRUCTION(FRT_RPCInvoker)
VESPA_CAN_SKIP_DESTRUCTION(FRT_HookInvoker)