@@ -279,7 +279,7 @@ FileChannelShared::~FileChannelShared() {
279279 // dead it means there was a problem to process a query or send back a response
280280 // to Czar. In either case, the file would be useless and it has to be deleted
281281 // in order to avoid leaving unclaimed result files within the results folder.
282- if (isDead ()) {
282+ if (_issueRequiresFileRemoval || isDead ()) {
283283 _removeFile (lock_guard<mutex>(_tMtx));
284284 }
285285 if (_sendChannel != nullptr ) {
@@ -329,6 +329,7 @@ bool FileChannelShared::buildAndTransmitError(util::MultiError& multiErr, shared
329329
330330bool FileChannelShared::buildAndTransmitResult (MYSQL_RES* mResult , shared_ptr<Task> const & task,
331331 util::MultiError& multiErr, atomic<bool >& cancelled) {
332+ LOGS (_log, LOG_LVL_WARN, " &&& FileChannelShared::buildAndTransmitResult start" );
332333 // Operation stats. Note that "buffer fill time" included the amount
333334 // of time needed to write the result set to disk.
334335 util::Timer transmitT;
@@ -348,22 +349,16 @@ bool FileChannelShared::buildAndTransmitResult(MYSQL_RES* mResult, shared_ptr<Ta
348349
349350 // &&& Arena may not really be needed.
350351 std::unique_ptr<google::protobuf::Arena> protobufArena = make_unique<google::protobuf::Arena>();
351- proto::ResponseData* responseData = 0 ;
352+ proto::ResponseData* responseData = nullptr ;
352353
353354 while (hasMoreRows && !cancelled) {
354- // This lock is to protect the stream from having other Tasks mess with it
355- // while data is loading.
356- lock_guard<mutex> const tMtxLockA (_tMtx);
357-
358355 util::Timer bufferFillT;
359356 bufferFillT.start ();
360357
361358 // Transfer as many rows as it's allowed by limitations of
362359 // the Google Protobuf into the output file.
363360 int bytes = 0 ;
364361 int rows = 0 ;
365- // &&& hasMoreRows = _writeToFile(tMtxLockA, task, mResult, bytes, rows, multiErr);
366-
367362 hasMoreRows = _writeToFile (responseData, protobufArena, task, mResult , bytes, rows, multiErr);
368363 bytesTransmitted += bytes;
369364 rowsTransmitted += rows;
@@ -394,15 +389,16 @@ bool FileChannelShared::buildAndTransmitResult(MYSQL_RES* mResult, shared_ptr<Ta
394389 // the current request (note that certain classes of requests may require
395390 // more than one task for processing).
396391 if (!hasMoreRows && transmitTaskLast ()) {
392+ LOGS (_log, LOG_LVL_WARN, " &&& FileChannelShared::buildAndTransmitResult e" );
397393 lock_guard<mutex> const tMtxLock (_tMtx);
394+ LOGS (_log, LOG_LVL_WARN, " &&& FileChannelShared::buildAndTransmitResult e1" );
398395
399396 // Make sure the file is sync to disk before notifying Czar.
400397 _file.flush ();
401398 _file.close ();
402399
403400 // Only the last ("summary") message, w/o any rows, is sent to the Czar to notify
404401 // it about the completion of the request.
405- // &&&if (!_sendResponse(tMtxLockA, task, cancelled, multiErr)) {
406402 if (!_sendResponse (tMtxLock, protobufArena, task, cancelled, multiErr)) {
407403 LOGS (_log, LOG_LVL_ERROR, " Could not transmit the request completion message to Czar." );
408404 erred = true ;
@@ -428,9 +424,14 @@ bool FileChannelShared::buildAndTransmitResult(MYSQL_RES* mResult, shared_ptr<Ta
428424 // successfully processing the query and writing all results into the file.
429425 // The file is not going to be used by Czar in either of these scenarios.
430426 if (cancelled || erred || isDead ()) {
427+ /* &&&
431428 //&&& it may be better to set a flag and call _removeFile in the destructor.
432429 lock_guard<mutex> const tMtxLockA(_tMtx);
433430 _removeFile(tMtxLockA);
431+ */
432+ // Set a flag to delete the file in the destructor. That should prevent any
433+ // possible race conditions with other threads expecting the file to exist.
434+ _issueRequiresFileRemoval = true ;
434435 }
435436 return erred;
436437}
@@ -445,19 +446,13 @@ bool FileChannelShared::_writeToFile(proto::ResponseData* responseData,
445446 shared_ptr<Task> const & task, MYSQL_RES* mResult , int & bytes, int & rows,
446447 util::MultiError& multiErr) {
447448 // Transfer rows from a result set into the response data object.
449+ LOGS (_log, LOG_LVL_WARN, " &&& _writeToFile start" );
448450 if (nullptr == responseData) {
449451 responseData = google::protobuf::Arena::CreateMessage<proto::ResponseData>(protobufArena.get ());
450452 } else {
451453 responseData->clear_row ();
452454 }
453455 size_t tSize = 0 ;
454- /* &&&
455- LOGS(_log, LOG_LVL_TRACE, __func__ << " _fillRows " << task->getIdStr() << " start");
456- bool const hasMoreRows = _fillRows(tMtxLock, mResult, rows, tSize);
457- LOGS(_log, LOG_LVL_TRACE, __func__ << " _fillRows " << task->getIdStr() << " end");
458- _responseData->set_rowcount(rows);
459- _responseData->set_transmitsize(tSize);
460- */
461456 bool const hasMoreRows = _fillRows (responseData, mResult , rows, tSize);
462457 responseData->set_rowcount (rows);
463458 responseData->set_transmitsize (tSize);
@@ -468,8 +463,10 @@ bool FileChannelShared::_writeToFile(proto::ResponseData* responseData,
468463 responseData->SerializeToString (&msg);
469464 bytes = msg.size ();
470465
471- // &&&LOGS(_log, LOG_LVL_TRACE, __func__ << " file write " << task->getIdStr() << " start");
466+ LOGS (_log, LOG_LVL_TRACE, __func__ << " file write " << task->getIdStr () << " start" );
467+ LOGS (_log, LOG_LVL_WARN, " &&& _writeToFile d" );
472468 lock_guard<mutex> const tMtxLock (_tMtx);
469+ LOGS (_log, LOG_LVL_WARN, " &&& _writeToFile d1" );
473470 // Create the file if not open.
474471 if (!_file.is_open ()) {
475472 _fileName = task->resultFilePath ();
@@ -491,6 +488,7 @@ bool FileChannelShared::_writeToFile(proto::ResponseData* responseData,
491488 throw runtime_error (" FileChannelShared::" + string (__func__) + " failed to write " +
492489 to_string (msg.size ()) + " bytes into the file '" + _fileName + " '." );
493490 }
491+ LOGS (_log, LOG_LVL_WARN, " &&& _writeToFile end" );
494492 return hasMoreRows;
495493}
496494
0 commit comments