1
0
Fork 0

fix crash in async request handling when request queue is full (#9029)

This commit is contained in:
Jan 2019-05-17 16:28:43 +02:00 committed by GitHub
parent 4d86dd5fa8
commit 8925edc131
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 93 additions and 2 deletions

View File

@ -1,6 +1,9 @@
v3.4.6 (XXXX-XX-XX)
-------------------
* fixed a crash when posting an async request to the server using the "x-arango-async"
request header and the server's request queue was full
* added error code 1240 "incomplete read" for RocksDB-based reads which cannot retrieve
documents due to the RocksDB block cache being size-restricted (with size limit enforced)
and uncompressed data blocks not fitting into the block cache

View File

@ -288,7 +288,7 @@ void GeneralCommTask::executeRequest(std::unique_ptr<GeneralRequest>&& request,
<< "could not find corresponding request/response";
}
rest::ContentType respType = request->contentTypeResponse();
rest::ContentType const respType = request->contentTypeResponse();
// create a handler, this takes ownership of request and response
std::shared_ptr<RestHandler> handler(
GeneralServerFeature::HANDLER_FACTORY->createHandler(std::move(request),
@ -326,6 +326,11 @@ void GeneralCommTask::executeRequest(std::unique_ptr<GeneralRequest>&& request,
ok = handleRequestAsync(std::move(handler));
}
TRI_IF_FAILURE("queueFull") {
ok = false;
jobId = 0;
}
if (ok) {
std::unique_ptr<GeneralResponse> response =
createResponse(rest::ResponseCode::ACCEPTED, messageId);
@ -338,7 +343,7 @@ void GeneralCommTask::executeRequest(std::unique_ptr<GeneralRequest>&& request,
addResponse(*response, nullptr);
} else {
addErrorResponse(rest::ResponseCode::SERVICE_UNAVAILABLE,
request->contentTypeResponse(), messageId, TRI_ERROR_QUEUE_FULL);
respType, messageId, TRI_ERROR_QUEUE_FULL);
}
} else {
// synchronous request

View File

@ -0,0 +1,83 @@
/*jshint globalstrict:false, strict:false */
/*global arango, assertTrue, assertFalse, assertEqual */
////////////////////////////////////////////////////////////////////////////////
/// @brief test async requests
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2015 triAGENS GmbH, Cologne, Germany
///
/// Licensed 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.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2015, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
let jsunity = require('jsunity');
////////////////////////////////////////////////////////////////////////////////
/// @brief test suite
////////////////////////////////////////////////////////////////////////////////
function AsyncRequestSuite () {
'use strict';
return {
testAsyncRequest() {
let res = arango.GET_RAW("/_api/version", { "x-arango-async" : "true" });
assertEqual(202, res.code);
assertFalse(res.headers.hasOwnProperty("x-arango-async-id"));
},
testAsyncRequestStore() {
let res = arango.GET_RAW("/_api/version", { "x-arango-async" : "store" });
assertEqual(202, res.code);
assertTrue(res.headers.hasOwnProperty("x-arango-async-id"));
const id = res.headers["x-arango-async-id"];
let tries = 0;
while (++tries < 30) {
res = arango.PUT_RAW("/_api/job/" + id, "");
if (res.code === 200) {
break;
}
require("internal").sleep(0.5);
}
assertEqual(200, res.code);
},
testAsyncRequestQueueFull() {
let res = arango.PUT_RAW("/_admin/debug/failat/queueFull", "");
if (res.code !== 200) {
// abort test - failure mode is not activated on server
return;
}
try {
res = arango.GET_RAW("/_api/version", { "x-arango-async" : "true" });
assertEqual(503, res.code);
} finally {
arango.DELETE("/_admin/debug/failat/queueFull");
}
},
};
}
jsunity.run(AsyncRequestSuite);
return jsunity.done();