MCPcopy Create free account
hub / github.com/apache/impala / ExpireQueries

Method ExpireQueries

be/src/service/impala-server.cc:3054–3177  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3052}
3053
3054[[noreturn]] void ImpalaServer::ExpireQueries() {
3055 while (true) {
3056 // The following block accomplishes four things:
3057 //
3058 // 1. Update the ordered list of queries by checking the 'idle_time' parameter in
3059 // client_request_state. We are able to avoid doing this for *every* query in flight
3060 // thanks to the observation that expiry times never move backwards, only
3061 // forwards. Therefore once we find a query that a) hasn't changed its idle time and
3062 // b) has not yet expired we can stop moving through the list. If the idle time has
3063 // changed, we need to re-insert the query in the right place in queries_by_timestamp_
3064 //
3065 // 2. Remove any queries that would have expired but have already been closed for any
3066 // reason.
3067 //
3068 // 3. Compute the next time a query *might* expire, so that the sleep at the end of
3069 // this loop has an accurate duration to wait. If the list of queries is empty, the
3070 // default sleep duration is half the idle query timeout.
3071 //
3072 // 4. Cancel queries with CPU and scan bytes constraints if limit is exceeded
3073 int64_t now;
3074 {
3075 lock_guard<mutex> l(query_expiration_lock_);
3076 ExpirationQueue::iterator expiration_event = queries_by_timestamp_.begin();
3077 now = UnixMillis();
3078 while (expiration_event != queries_by_timestamp_.end()) {
3079 // 'queries_by_timestamp_' is stored in ascending order of deadline so we can
3080 // break out of the loop and sleep as soon as we see a deadline in the future.
3081 if (expiration_event->deadline > now) break;
3082 shared_ptr<QueryDriver> query_driver = GetQueryDriver(expiration_event->query_id);
3083 if (query_driver == nullptr) {
3084 // Query was deleted already from a previous expiration event
3085 expiration_event = queries_by_timestamp_.erase(expiration_event);
3086 continue;
3087 }
3088 ClientRequestState* crs = query_driver->GetActiveClientRequestState();
3089 if (crs->is_expired() && expiration_event->kind != ExpirationKind::IDLE_TIMEOUT) {
3090 // Query was expired already from a previous expiration event. Keep idle
3091 // timeouts as they will additionally unregister the query.
3092 expiration_event = queries_by_timestamp_.erase(expiration_event);
3093 continue;
3094 }
3095
3096 // Check for CPU and scanned bytes limits
3097 if (expiration_event->kind == ExpirationKind::RESOURCE_LIMIT) {
3098 Status resource_status = CheckResourceLimits(crs);
3099 if (resource_status.ok()) {
3100 queries_by_timestamp_.emplace(
3101 ExpirationEvent{now + EXPIRATION_CHECK_INTERVAL_MS,
3102 expiration_event->query_id, ExpirationKind::RESOURCE_LIMIT});
3103 } else {
3104 ExpireQuery(crs, resource_status);
3105 }
3106 expiration_event = queries_by_timestamp_.erase(expiration_event);
3107 continue;
3108 }
3109
3110 // If the query time limit expired, we must cancel the query.
3111 if (expiration_event->kind == ExpirationKind::EXEC_TIME_LIMIT) {

Callers

nothing calls this directly

Calls 14

UnixMillisFunction · 0.85
PrintIdFunction · 0.85
GetIdleTimeoutFunction · 0.85
DebugActionNoFailFunction · 0.85
eraseMethod · 0.80
is_expiredMethod · 0.80
last_active_msMethod · 0.80
is_activeMethod · 0.80
MergeStatusMethod · 0.80
beginMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected