Coverage Report

Created: 2026-10-14 15:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/load/channel/load_channel.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <atomic>
21
#include <cstdint>
22
#include <memory>
23
#include <mutex>
24
#include <ostream>
25
#include <string>
26
#include <unordered_map>
27
#include <unordered_set>
28
#include <utility>
29
30
#include "common/status.h"
31
#include "runtime/runtime_profile.h"
32
#include "runtime/workload_group/workload_group_fwd.h"
33
#include "runtime/workload_management/resource_context.h"
34
#include "util/uid_util.h"
35
36
namespace doris {
37
38
class EosCompletion;
39
class PTabletWriterOpenRequest;
40
class PTabletWriterAddBlockRequest;
41
class PTabletWriterAddBlockResult;
42
class OpenPartitionRequest;
43
class BaseTabletsChannel;
44
class AtomicStatus;
45
46
// A LoadChannel manages tablets channels for all indexes
47
// corresponding to a certain load job
48
class LoadChannel {
49
public:
50
    LoadChannel(const UniqueId& load_id, int64_t timeout_s, bool is_high_priority,
51
                std::string sender_ip, int64_t backend_id, bool enable_profile, int64_t wg_id);
52
    ~LoadChannel();
53
54
    // open a new load channel if not exist
55
    Status open(const PTabletWriterOpenRequest& request);
56
57
    // This batch must belong to one index in one transaction. For hang_wait EOS,
58
    // return the sender-arrival barrier in eos_completion. Final flush/commit
59
    // stays synchronous on the last sender. The caller must register its RPC
60
    // completion only after all synchronous request/response access has ended.
61
    Status add_batch(const PTabletWriterAddBlockRequest& request,
62
                     PTabletWriterAddBlockResult* response,
63
                     std::shared_ptr<EosCompletion>* eos_completion);
64
65
    // return true if this load channel has been opened and all tablets channels are closed then.
66
    bool is_finished();
67
68
    // Publish cancellation without taking channel/writer locks. In-flight
69
    // requests retain ownership and release writers after their work finishes.
70
    Status cancel(const Status& reason = Status::Cancelled("load channel cancelled"));
71
    Status cancel_status() const;
72
73
150
    time_t last_updated_time() const { return _last_updated_time.load(); }
74
75
31.9k
    const UniqueId& load_id() const { return _load_id; }
76
77
151
    int64_t timeout() const { return _timeout_s; }
78
79
57.4k
    bool is_high_priority() const { return _is_high_priority; }
80
81
    bool is_cancelled() const;
82
83
56.9k
    WorkloadGroupPtr workload_group() const { return _resource_ctx->workload_group(); }
84
85
57.4k
    RuntimeProfile::Counter* get_mgr_add_batch_timer() { return _mgr_add_batch_timer; }
86
56.9k
    RuntimeProfile::Counter* get_handle_mem_limit_timer() { return _handle_mem_limit_timer; }
87
88
protected:
89
    Status _get_tablets_channel(std::shared_ptr<BaseTabletsChannel>& channel, bool& is_finished,
90
                                int64_t index_id);
91
92
    Status _handle_eos(BaseTabletsChannel* channel, const PTabletWriterAddBlockRequest& request,
93
                       PTabletWriterAddBlockResult* response);
94
95
    void _init_profile();
96
    // thread safety
97
    void _report_profile(PTabletWriterAddBlockResult* response);
98
99
private:
100
    UniqueId _load_id;
101
    int64_t _txn_id = 0;
102
103
    std::mutex _profile_serialize_lock;
104
    std::unique_ptr<RuntimeProfile> _profile;
105
    RuntimeProfile* _self_profile = nullptr;
106
    RuntimeProfile::Counter* _add_batch_number_counter = nullptr;
107
    RuntimeProfile::Counter* _add_batch_timer = nullptr;
108
    RuntimeProfile::Counter* _add_batch_times = nullptr;
109
    RuntimeProfile::Counter* _mgr_add_batch_timer = nullptr;
110
    RuntimeProfile::Counter* _handle_mem_limit_timer = nullptr;
111
    RuntimeProfile::Counter* _handle_eos_timer = nullptr;
112
113
    // lock protect the tablets channel map
114
    std::mutex _lock;
115
    // index id -> tablets channel
116
    std::unordered_map<int64_t, std::shared_ptr<BaseTabletsChannel>> _tablets_channels;
117
    // index id -> (received rows, filtered rows)
118
    std::unordered_map<int64_t, std::pair<size_t, size_t>> _tablets_channels_rows;
119
    std::mutex _tablets_channels_lock;
120
    // This is to save finished channels id, to handle the retry request.
121
    std::unordered_set<int64_t> _finished_channel_ids;
122
    // set to true if at least one tablets channel has been opened
123
    bool _opened = false;
124
    const std::shared_ptr<AtomicStatus> _cancel_status;
125
126
    std::shared_ptr<ResourceContext> _resource_ctx;
127
128
    std::atomic<time_t> _last_updated_time;
129
130
    // the timeout of this load job.
131
    // Timed out channels will be periodically deleted by LoadChannelMgr.
132
    int64_t _timeout_s;
133
134
    // true if this is a high priority load task
135
    bool _is_high_priority = false;
136
137
    // the ip where tablet sink locate
138
    std::string _sender_ip;
139
140
    int64_t _backend_id;
141
142
    bool _enable_profile;
143
};
144
145
2
inline std::ostream& operator<<(std::ostream& os, LoadChannel& load_channel) {
146
2
    os << "LoadChannel(id=" << load_channel.load_id()
147
2
       << ", last_update_time=" << static_cast<uint64_t>(load_channel.last_updated_time())
148
2
       << ", is high priority: " << load_channel.is_high_priority() << ")";
149
2
    return os;
150
2
}
151
152
} // namespace doris