| 123 | {} |
| 124 | |
| 125 | Status QueryScanner::Open() { |
| 126 | ImpalaServer* server = ExecEnv::GetInstance()->impala_server(); |
| 127 | |
| 128 | // Get a sorted list of state snapshots for all active queries. This mimics the |
| 129 | // behavior of ImpalaHttpHandler::QueryStateHandler. Using snapshots avoids potential |
| 130 | // memory violations of trying to use a ClientRequestState pointer without holding a |
| 131 | // shared_ptr to the QueryDriver and avoids keeping the query open longer than |
| 132 | // necessary (via that shared_ptr). The cost is that we allocate memory for the |
| 133 | // QueryStateRecords, which should be relatively small. |
| 134 | { |
| 135 | SCOPED_TIMER(active_query_collection_timer_); |
| 136 | server->query_driver_map_.DoFuncForAllEntries( |
| 137 | [&](const std::shared_ptr<QueryDriver>& query_driver) { |
| 138 | query_records_.emplace_back(make_shared<QueryStateExpanded>( |
| 139 | *query_driver->GetActiveClientRequestState())); |
| 140 | }); |
| 141 | } |
| 142 | |
| 143 | unordered_set<TUniqueId> running_queries; |
| 144 | running_queries.reserve(query_records_.size()); |
| 145 | for (const auto& r : query_records_) { |
| 146 | running_queries.insert(r->base_state->id); |
| 147 | } |
| 148 | |
| 149 | // It's possible for a query to appear in both query_driver_map_ and completed_queries_ |
| 150 | // if it's been added to completed_queries_ in CloseClientRequestState and has not yet |
| 151 | // been removed from query_driver_map_ in QueryDriver::Unregister. Collection order |
| 152 | // ensures we don't miss one by collecting before it's been added to completed_queries_, |
| 153 | // then after it's added to completed_queries_ and removed from query_driver_map_. |
| 154 | // Avoid adding entries if they already exist. |
| 155 | { |
| 156 | SCOPED_TIMER(pending_query_collection_timer_); |
| 157 | for (const auto& r : server->GetCompletedQueries()) { |
| 158 | if (running_queries.find(r->base_state->id) == running_queries.end()) { |
| 159 | query_records_.emplace_back(r); |
| 160 | } |
| 161 | } |
| 162 | } |
| 163 | |
| 164 | if (query_records_.empty()) eos_ = true; |
| 165 | return Status::OK(); |
| 166 | } |
| 167 | |
| 168 | static void WriteEvent(const QueryStateExpanded& query, const SlotDescriptor* slot_desc, |
| 169 | void* slot, QueryEvent name) { |
nothing calls this directly
no test coverage detected