blob: f4a87271f3f998a2f4e976c76247f5ffefdd3e73 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <vector>
#include "common/status.h"
#include "gen-cpp/Types_types.h"
namespace impala {
/// Categorisation of causes of cancellation.
enum class CancellationWorkCause {
// The Impala Server terminated the query, e.g. because it exceeded a timeout or
// resource limit.
TERMINATED_BY_SERVER,
// The query is being terminated because a backend failed. We can skip cancelling the
// query if the fragment instances running on that backend all completed.
BACKEND_FAILED
};
/// Work item for ImpalaServer::cancellation_thread_pool_.
/// This class needs to support move construction and assignment for use in ThreadPool.
class CancellationWork {
public:
// Empty constructor needed to make ThreadPool happy.
CancellationWork()
: cause_(CancellationWorkCause::TERMINATED_BY_SERVER), unregister_(false) {}
// Construct a TERMINATED_BY_SERVER CancellationWork instance.
static CancellationWork TerminatedByServer(
const TUniqueId& query_id, const Status& error, bool unregister) {
return CancellationWork(
query_id, CancellationWorkCause::TERMINATED_BY_SERVER, error, {}, unregister);
}
// Construct a BACKEND_FAILURE CancellationWork instance.
static CancellationWork BackendFailure(const TUniqueId& query_id,
const std::vector<TNetworkAddress>& failed_backends) {
return CancellationWork(query_id, CancellationWorkCause::BACKEND_FAILED, Status::OK(),
failed_backends, false);
}
const TUniqueId& query_id() const { return query_id_; }
CancellationWorkCause cause() const { return cause_; }
const Status& error() const {
DCHECK_ENUM_EQ(cause_, CancellationWorkCause::TERMINATED_BY_SERVER);
return error_;
}
const std::vector<TNetworkAddress>& failed_backends() const {
DCHECK_ENUM_EQ(cause_, CancellationWorkCause::BACKEND_FAILED);
return failed_backends_;
}
bool unregister() const { return unregister_; }
private:
CancellationWork(const TUniqueId& query_id, CancellationWorkCause cause,
const Status& error, const std::vector<TNetworkAddress>& failed_backends,
bool unregister)
: query_id_(query_id),
cause_(cause),
error_(error),
failed_backends_(failed_backends),
unregister_(unregister) {
DCHECK(cause_ != CancellationWorkCause::TERMINATED_BY_SERVER || !error.ok());
DCHECK(cause_ != CancellationWorkCause::BACKEND_FAILED || !failed_backends.empty());
}
// ID of query to be cancelled.
TUniqueId query_id_;
// Cause of the expiration.
CancellationWorkCause cause_;
// If 'cause_' is TERMINATED_BY_SERVER, the error containing human-readable explanation
// of the cancellation. Otherwise not used.
Status error_;
// If cause is BACKEND_FAILED, all of the backend that were detected to fail. Otherwise
// not used.
std::vector<TNetworkAddress> failed_backends_;
// If true, unregister the query after cancelling it.
bool unregister_;
};
} // namespace impala