aboutsummaryrefslogtreecommitdiffstats
path: root/persistence/src/vespa/persistence/spi/context.h
blob: 590acd1c54958aad7c0c14c1b0d8f789c34aa4bd (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
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
/**
 * The context object is used to pass optional per operation data down to the
 * persistence layer. It contains the following:
 *
 * The load type of the operation. Users can tag their load with load types,
 * such that the backend can be configured to handle them differently. This can
 * for instance be used to:
 *   - Control what should be cached.
 *   - Keep different metrics per load type, such that users can see metrics of
 *     what they are interested in without getting them polluted with data from
 *     other types of load.
 *
 * The priority used by the service layer is given. The service layer keeps a
 * priority queue so the highest priority operations pending should be issued
 * first, but priority can also be useful in the provider, for instance for the
 * following:
 *   - Prioritize load through SPI against other load in provider.
 *   - Pause low priority load when we have high priority load running at the
 *     same time using the same resources.
 *
 * Our messagebus protocol allows tracing, which simplifies debugging. For
 * instance, if some operation is slow, one can add tracing and see where it
 * uses time, whether it has hit caches etc. As the persistence provider itself
 * can become complex, we want that also to be able to add to the trace. Thus we
 * want to give it a way to specify something that we will add to the mbus
 * trace.
 */

#pragma once

#include "read_consistency.h"
#include <vespa/vespalib/trace/trace.h>

namespace storage::spi {

using Priority = uint16_t; // 0 - max pri, 255 - min pri

// Define this type just because a ton of tests currently use it.
struct Trace {
    using TraceLevel = int;
};

class Context {
    Priority _priority;
    vespalib::Trace _trace;
    ReadConsistency _readConsistency;
public:
    Context(Context &&) noexcept = default;
    Context & operator = (Context &&) noexcept = default;
    Context(Priority pri, int maxTraceLevel) noexcept;
    ~Context();

    Priority getPriority() const noexcept { return _priority; }

    /**
     * A read operation might choose to relax its consistency requirements,
     * allowing the persistence provider to perform optimizations on the
     * operation as a result.
     *
     * A persistence provider is not required to support relaxed consistency
     * and it might only support this on a subset of read operations, so this
     * should only be considered a hint.
     */
    void setReadConsistency(ReadConsistency consistency) noexcept {
        _readConsistency = consistency;
    }
    ReadConsistency getReadConsistency() const noexcept {
        return _readConsistency;
    }

    vespalib::Trace && steal_trace() noexcept { return std::move(_trace); }
    vespalib::Trace& getTrace() noexcept { return _trace; }
    const vespalib::Trace& getTrace() const noexcept { return _trace; }

    bool shouldTrace(int level) noexcept { return _trace.shouldTrace(level); }
    void trace(int level, vespalib::stringref msg, bool addTime = true) {
        _trace.trace(level, msg, addTime);
    }
};

}