aboutsummaryrefslogtreecommitdiffstats
path: root/fnet/src/vespa/fnet/frt/rpcrequest.h
blob: 72dae4a6af1334b225232ddf7ab1ad83f2432286 (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
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#pragma once

#include "values.h"
#include "error.h"
#include <vespa/fnet/context.h>
#include <vespa/vespalib/util/stash.h>
#include <vespa/vespalib/util/ref_counted.h>
#include <atomic>

class FNET_Packet;

class FRT_IAbortHandler
{
public:

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

    virtual bool HandleAbort() = 0;
};


class FRT_IReturnHandler
{
public:

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

    virtual void HandleReturn() = 0;
    virtual FNET_Connection *GetConnection() = 0;
};


class FRT_RPCRequest : public vespalib::enable_ref_counted
{
private:
    using Stash = vespalib::Stash;
    Stash            _stash;
    FNET_Context     _context;
    FRT_Values       _params;
    FRT_Values       _return;
    std::atomic<int> _completed;
    uint32_t         _errorCode;
    uint32_t         _errorMessageLen;
    uint32_t         _methodNameLen;
    char            *_errorMessage;
    char            *_methodName;

    bool                *_detachedPT;
    FRT_IAbortHandler   *_abortHandler;
    FRT_IReturnHandler  *_returnHandler;

public:
    FRT_RPCRequest(const FRT_RPCRequest &) = delete;
    FRT_RPCRequest &operator=(const FRT_RPCRequest &) = delete;
    FRT_RPCRequest();
    ~FRT_RPCRequest();

    void Reset();
    bool Recycle();

    void DiscardBlobs()
    {
        _params.DiscardBlobs();
        _return.DiscardBlobs();
    }

    void SetContext(FNET_Context context) { _context = context; }
    FNET_Context GetContext() { return _context; }

    Stash & getStash() { return _stash; }

    FRT_Values *GetParams() { return &_params; }
    FRT_Values *GetReturn() { return &_return; }

    const char *GetParamSpec()
    {
        const char *spec = _params.GetTypeString();
        return (spec != nullptr) ? spec : "";
    }
    const char *GetReturnSpec()
    {
        const char *spec = _return.GetTypeString();
        return (spec != nullptr) ? spec : "";
    }

    bool GetCompletionToken() { return (_completed.fetch_add(1) == 0); }

    void SetError(uint32_t errorCode, const char *errorMessage, uint32_t errorMessageLen);
    void SetError(uint32_t errorCode, const char *errorMessage);
    void SetError(uint32_t errorCode);

    bool IsError() { return (_errorCode != FRTE_NO_ERROR); }
    uint32_t GetErrorCode() { return _errorCode; }
    uint32_t GetErrorMessageLen() { return _errorMessageLen; }
    const char *GetErrorMessage() { return _errorMessage; }

    bool CheckReturnTypes(const char *types);

    void SetMethodName(const char *methodName, uint32_t len);
    void SetMethodName(const char *methodName);

    uint32_t GetMethodNameLen() const { return _methodNameLen; }
    const char *GetMethodName() const { return _methodName; }

    void Print(uint32_t indent = 0);

    FNET_Packet *CreateRequestPacket(bool wantReply);
    FNET_Packet *CreateReplyPacket();

    void SetDetachedPT(bool *detachedPT) { _detachedPT = detachedPT; }
    FRT_RPCRequest *Detach() { *_detachedPT = true; return this; }

    void SetAbortHandler(FRT_IAbortHandler *handler) { _abortHandler = handler; }
    void SetReturnHandler(FRT_IReturnHandler *handler) { _returnHandler = handler; }

    bool Abort();
    void Return();
    FNET_Connection *GetConnection();
};