summaryrefslogtreecommitdiffstats
path: root/storage
diff options
context:
space:
mode:
authorGeir Storli <geirst@verizonmedia.com>2021-01-19 12:30:54 +0000
committerGeir Storli <geirst@verizonmedia.com>2021-01-19 12:30:54 +0000
commita2a032e2cd01124298977abc7dc6796111b4e049 (patch)
treef5a0fd34e63285d4b5b480ca8ec8d86733351d94 /storage
parent4b4938c47dd4c1cbb37ac22e7436f0ec2d2754fe (diff)
Reject non-trivial updates if feed is blocked in the cluster.
Diffstat (limited to 'storage')
-rw-r--r--storage/src/tests/distributor/externaloperationhandlertest.cpp35
-rw-r--r--storage/src/vespa/storage/distributor/externaloperationhandler.cpp40
-rw-r--r--storage/src/vespa/storage/distributor/externaloperationhandler.h1
3 files changed, 56 insertions, 20 deletions
diff --git a/storage/src/tests/distributor/externaloperationhandlertest.cpp b/storage/src/tests/distributor/externaloperationhandlertest.cpp
index eae7ad7fcde..a95418b0b74 100644
--- a/storage/src/tests/distributor/externaloperationhandlertest.cpp
+++ b/storage/src/tests/distributor/externaloperationhandlertest.cpp
@@ -1,19 +1,20 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <tests/distributor/distributortestutil.h>
-#include <vespa/storage/distributor/externaloperationhandler.h>
+#include <vespa/document/fieldset/fieldsets.h>
+#include <vespa/document/repo/documenttyperepo.h>
+#include <vespa/document/test/make_document_bucket.h>
+#include <vespa/document/update/assignvalueupdate.h>
+#include <vespa/document/update/documentupdate.h>
+#include <vespa/storage/common/reindexing_constants.h>
#include <vespa/storage/distributor/distributor.h>
#include <vespa/storage/distributor/distributor_bucket_space.h>
#include <vespa/storage/distributor/distributormetricsset.h>
+#include <vespa/storage/distributor/externaloperationhandler.h>
#include <vespa/storage/distributor/operations/external/getoperation.h>
#include <vespa/storage/distributor/operations/external/read_for_write_visitor_operation.h>
-#include <vespa/storage/common/reindexing_constants.h>
#include <vespa/storageapi/message/persistence.h>
#include <vespa/storageapi/message/visitor.h>
-#include <vespa/document/repo/documenttyperepo.h>
-#include <vespa/document/update/documentupdate.h>
-#include <vespa/document/fieldset/fieldsets.h>
-#include <vespa/document/test/make_document_bucket.h>
#include <vespa/vespalib/gtest/gtest.h>
using document::test::makeDocumentBucket;
@@ -582,6 +583,28 @@ TEST_F(ExternalOperationHandlerTest, puts_are_rejected_if_feed_is_blocked) {
_sender.reply(0)->getResult().toString());
}
+TEST_F(ExternalOperationHandlerTest, non_trivial_updates_are_rejected_if_feed_is_blocked) {
+ set_up_distributor_with_feed_blocked_state();
+
+ auto cmd = makeUpdateCommand("testdoctype1", "id:foo:testdoctype1::foo");
+ const auto* doc_type = _testDocMan.getTypeRepo().getDocumentType("testdoctype1");
+ document::FieldUpdate upd(doc_type->getField("title"));
+ upd.addUpdate(document::AssignValueUpdate(document::StringFieldValue("new value")));
+ cmd->getUpdate()->addUpdate(upd);
+
+ ASSERT_NO_FATAL_FAILURE(start_operation_verify_rejected(std::move(cmd)));
+ EXPECT_EQ("ReturnCode(NO_SPACE, External feed is blocked due to resource exhaustion: full disk)",
+ _sender.reply(0)->getResult().toString());
+}
+
+TEST_F(ExternalOperationHandlerTest, trivial_updates_are_not_rejected_if_feed_is_blocked) {
+ set_up_distributor_with_feed_blocked_state();
+
+ Operation::SP generated;
+ ASSERT_NO_FATAL_FAILURE(start_operation_verify_not_rejected(
+ makeUpdateCommand("testdoctype1", "id:foo:testdoctype1::foo"), generated));
+}
+
struct OperationHandlerSequencingTest : ExternalOperationHandlerTest {
void SetUp() override {
diff --git a/storage/src/vespa/storage/distributor/externaloperationhandler.cpp b/storage/src/vespa/storage/distributor/externaloperationhandler.cpp
index 1e76e701a7e..ebca3574eac 100644
--- a/storage/src/vespa/storage/distributor/externaloperationhandler.cpp
+++ b/storage/src/vespa/storage/distributor/externaloperationhandler.cpp
@@ -2,26 +2,27 @@
#include "bucket_space_distribution_context.h"
#include "crypto_uuid_generator.h"
-#include "externaloperationhandler.h"
#include "distributor.h"
+#include "distributor_bucket_space.h"
+#include "distributor_bucket_space_repo.h"
+#include "externaloperationhandler.h"
#include "operation_sequencer.h"
#include <vespa/document/base/documentid.h>
-#include <vespa/storage/distributor/operations/external/putoperation.h>
-#include <vespa/storage/distributor/operations/external/twophaseupdateoperation.h>
-#include <vespa/storage/distributor/operations/external/updateoperation.h>
-#include <vespa/storage/distributor/operations/external/removeoperation.h>
+#include <vespa/document/util/feed_reject_helper.h>
+#include <vespa/storage/common/reindexing_constants.h>
#include <vespa/storage/distributor/operations/external/getoperation.h>
-#include <vespa/storage/distributor/operations/external/statbucketoperation.h>
-#include <vespa/storage/distributor/operations/external/statbucketlistoperation.h>
+#include <vespa/storage/distributor/operations/external/putoperation.h>
#include <vespa/storage/distributor/operations/external/read_for_write_visitor_operation.h>
#include <vespa/storage/distributor/operations/external/removelocationoperation.h>
+#include <vespa/storage/distributor/operations/external/removeoperation.h>
+#include <vespa/storage/distributor/operations/external/statbucketlistoperation.h>
+#include <vespa/storage/distributor/operations/external/statbucketoperation.h>
+#include <vespa/storage/distributor/operations/external/twophaseupdateoperation.h>
+#include <vespa/storage/distributor/operations/external/updateoperation.h>
#include <vespa/storage/distributor/operations/external/visitoroperation.h>
-#include <vespa/storage/common/reindexing_constants.h>
#include <vespa/storageapi/message/persistence.h>
#include <vespa/storageapi/message/removelocation.h>
#include <vespa/storageapi/message/stat.h>
-#include "distributor_bucket_space_repo.h"
-#include "distributor_bucket_space.h"
#include <vespa/log/log.h>
#include <vespa/document/bucket/fixed_bucket_spaces.h>
@@ -136,6 +137,13 @@ void ExternalOperationHandler::bounce_with_result(api::StorageCommand& cmd, cons
_msg_sender.sendUp(std::shared_ptr<api::StorageMessage>(reply.release()));
}
+void ExternalOperationHandler::bounce_with_feed_blocked(api::StorageCommand& cmd) {
+ const auto& feed_block = _op_ctx.cluster_state_bundle().feed_block();
+ bounce_with_result(cmd, api::ReturnCode(api::ReturnCode::NO_SPACE,
+ "External feed is blocked due to resource exhaustion: " +
+ feed_block->description()));
+}
+
void ExternalOperationHandler::bounce_with_wrong_distribution(api::StorageCommand& cmd,
const lib::ClusterState& cluster_state)
{
@@ -285,10 +293,7 @@ std::string extract_reindexing_token(const api::PutCommand& cmd) {
bool ExternalOperationHandler::onPut(const std::shared_ptr<api::PutCommand>& cmd) {
if (_op_ctx.cluster_state_bundle().block_feed_in_cluster()) {
- const auto& feed_block = _op_ctx.cluster_state_bundle().feed_block();
- bounce_with_result(*cmd, api::ReturnCode(api::ReturnCode::NO_SPACE,
- "External feed is blocked due to resource exhaustion: " +
- feed_block->description()));
+ bounce_with_feed_blocked(*cmd);
return true;
}
@@ -335,6 +340,13 @@ bool ExternalOperationHandler::onPut(const std::shared_ptr<api::PutCommand>& cmd
bool ExternalOperationHandler::onUpdate(const std::shared_ptr<api::UpdateCommand>& cmd) {
+ if (_op_ctx.cluster_state_bundle().block_feed_in_cluster() &&
+ document::FeedRejectHelper::mustReject(*cmd->getUpdate()))
+ {
+ bounce_with_feed_blocked(*cmd);
+ return true;
+ }
+
auto& metrics = getMetrics().updates;
if (!checkTimestampMutationPreconditions(*cmd, _op_ctx.make_split_bit_constrained_bucket_id(cmd->getDocumentId()), metrics)) {
return true;
diff --git a/storage/src/vespa/storage/distributor/externaloperationhandler.h b/storage/src/vespa/storage/distributor/externaloperationhandler.h
index 9127325702a..1d42f4b3ca8 100644
--- a/storage/src/vespa/storage/distributor/externaloperationhandler.h
+++ b/storage/src/vespa/storage/distributor/externaloperationhandler.h
@@ -118,6 +118,7 @@ private:
const lib::ClusterState& current_state,
const lib::ClusterState& pending_state);
void bounce_with_result(api::StorageCommand& cmd, const api::ReturnCode& result);
+ void bounce_with_feed_blocked(api::StorageCommand& cmd);
std::shared_ptr<Operation> try_generate_get_operation(const std::shared_ptr<api::GetCommand>&);
bool checkSafeTimeReached(api::StorageCommand& cmd);