Commit 2b157e07 authored by David COME's avatar David COME
Browse files

Handle now exception in {Migration/Recall}TaskInjector if we cant get information from the client.

No answer = end of session
parent f69df258
...@@ -145,8 +145,25 @@ namespace daemon { ...@@ -145,8 +145,25 @@ namespace daemon {
castor::tape::threading::MutexLocker ml(&m_producerProtection); castor::tape::threading::MutexLocker ml(&m_producerProtection);
m_queue.push(Request()); m_queue.push(Request());
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//signalEndDataMovement
//------------------------------------------------------------------------------
void MigrationTaskInjector::signalEndDataMovement(){
//first send the end signal to the threads
m_tapeWriter.finish();
m_diskReader.finish();
m_memManager.finish();
}
//------------------------------------------------------------------------------
//deleteAllTasks
//------------------------------------------------------------------------------
void MigrationTaskInjector::deleteAllTasks(){
//discard all the tasks !!
while(m_queue.size()>0){
m_queue.pop();
}
}
//------------------------------------------------------------------------------
//WorkerThread::run //WorkerThread::run
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void MigrationTaskInjector::WorkerThread::run(){ void MigrationTaskInjector::WorkerThread::run(){
...@@ -159,14 +176,14 @@ namespace daemon { ...@@ -159,14 +176,14 @@ namespace daemon {
} }
Request req = m_parent.m_queue.pop(); Request req = m_parent.m_queue.pop();
client::ClientProxy::RequestReport reqReport; client::ClientProxy::RequestReport reqReport;
std::auto_ptr<tapegateway::FilesToMigrateList> filesToMigrateList(m_parent.m_client.getFilesToMigrate(req.nbMaxFiles, req.byteSizeThreshold,reqReport)); std::auto_ptr<tapegateway::FilesToMigrateList> filesToMigrateList(
m_parent.m_client.getFilesToMigrate(req.nbMaxFiles, req.byteSizeThreshold,reqReport)
);
if(NULL==filesToMigrateList.get()){ if(NULL==filesToMigrateList.get()){
if (req.lastCall) { if (req.lastCall) {
m_parent.m_lc.log(LOG_INFO,"No more file to migrate: triggering the end of session.\n"); m_parent.m_lc.log(LOG_INFO,"No more file to migrate: triggering the end of session.\n");
m_parent.m_tapeWriter.finish(); m_parent.signalEndDataMovement();
m_parent.m_diskReader.finish();
m_parent.m_memManager.finish();
break; break;
} else { } else {
m_parent.m_lc.log(LOG_INFO,"In MigrationTaskInjector::WorkerThread::run(): got empty list, but not last call"); m_parent.m_lc.log(LOG_INFO,"In MigrationTaskInjector::WorkerThread::run(): got empty list, but not last call");
...@@ -181,15 +198,22 @@ namespace daemon { ...@@ -181,15 +198,22 @@ namespace daemon {
m_parent.m_lc.log(LOG_ERR,"In MigrationTaskInjector::WorkerThread::run(): a task screw up, " m_parent.m_lc.log(LOG_ERR,"In MigrationTaskInjector::WorkerThread::run(): a task screw up, "
"finishing and discarding all tasks "); "finishing and discarding all tasks ");
//first send the end signal to the threads m_parent.signalEndDataMovement();
m_parent.m_tapeWriter.finish(); m_parent.deleteAllTasks();
m_parent.m_diskReader.finish(); }
catch(const castor::exception::Exception& ex){
//we end up there because we could not talk to the client
log::ScopedParamContainer container( m_parent.m_lc);
container.add("exception code",ex.code())
.add("exception message",ex.getMessageValue());
m_parent.m_lc.logBacktrace(LOG_ERR,ex.backtrace());
m_parent.m_lc.log(LOG_ERR,"In MigrationTaskInjector::WorkerThread::run(): "
"could not retrieve a list of file to migrate. End of session");
//discard all the tasks !! m_parent.signalEndDataMovement();
while(m_parent.m_queue.size()>0){ m_parent.deleteAllTasks();
m_parent.m_queue.pop(); }
}
} // end of while(1)
//------------- //-------------
m_parent.m_lc.log(LOG_INFO, "Finishing MigrationTaskInjector thread"); m_parent.m_lc.log(LOG_INFO, "Finishing MigrationTaskInjector thread");
/* We want to finish at the first lastCall we encounter. /* We want to finish at the first lastCall we encounter.
......
...@@ -114,6 +114,16 @@ private: ...@@ -114,6 +114,16 @@ private:
return fileSize/blockCapacity + ((fileSize%blockCapacity==0) ? 0 : 1); return fileSize/blockCapacity + ((fileSize%blockCapacity==0) ? 0 : 1);
} }
/**
* It will signal to the disk read thread pool, tape write single thread
* and to the mem manager they have to stop their threads(s)
*/
void signalEndDataMovement();
/**
* It will delete all remaining tasks
*/
void deleteAllTasks();
/** /**
* A request of files to migrate. We request EITHER * A request of files to migrate. We request EITHER
* - a maximum of nbMaxFiles files * - a maximum of nbMaxFiles files
......
...@@ -138,55 +138,86 @@ bool RecallTaskInjector::synchronousInjection() ...@@ -138,55 +138,86 @@ bool RecallTaskInjector::synchronousInjection()
return true; return true;
} }
} }
//------------------------------------------------------------------------------
//signalEndDataMovement
//------------------------------------------------------------------------------
void RecallTaskInjector::signalEndDataMovement(){
//first send the end signal to the threads
m_tapeReader.finish();
m_diskWriter.finish();
}
//------------------------------------------------------------------------------
//deleteAllTasks
//------------------------------------------------------------------------------
void RecallTaskInjector::deleteAllTasks(){
//discard all the tasks !!
while(m_queue.size()>0){
m_queue.pop();
}
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//WorkerThread::run //WorkerThread::run
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void RecallTaskInjector::WorkerThread::run() void RecallTaskInjector::WorkerThread::run()
{ {
using castor::log::LogContext; using castor::log::LogContext;
_this.m_lc.pushOrReplace(Param("thread", "recallTaskInjector")); m_parent.m_lc.pushOrReplace(Param("thread", "recallTaskInjector"));
_this.m_lc.log(LOG_DEBUG, "Starting RecallTaskInjector thread"); m_parent.m_lc.log(LOG_DEBUG, "Starting RecallTaskInjector thread");
while (1) { try{
Request req = _this.m_queue.pop(); while (1) {
_this.m_lc.log(LOG_INFO,"RecallJobInjector:run: about to call client interface\n"); Request req = m_parent.m_queue.pop();
client::ClientProxy::RequestReport reqReport; m_parent.m_lc.log(LOG_INFO,"RecallJobInjector:run: about to call client interface\n");
std::auto_ptr<tapegateway::FilesToRecallList> filesToRecallList(_this.m_client.getFilesToRecall(req.nbMaxFiles, req.byteSizeThreshold,reqReport)); client::ClientProxy::RequestReport reqReport;
std::auto_ptr<tapegateway::FilesToRecallList> filesToRecallList(m_parent.m_client.getFilesToRecall(req.nbMaxFiles, req.byteSizeThreshold,reqReport));
LogContext::ScopedParam sp01(_this.m_lc, Param("transactionId", reqReport.transactionId));
LogContext::ScopedParam sp02(_this.m_lc, Param("connectDuration", reqReport.connectDuration)); LogContext::ScopedParam sp01(m_parent.m_lc, Param("transactionId", reqReport.transactionId));
LogContext::ScopedParam sp03(_this.m_lc, Param("sendRecvDuration", reqReport.sendRecvDuration)); LogContext::ScopedParam sp02(m_parent.m_lc, Param("connectDuration", reqReport.connectDuration));
LogContext::ScopedParam sp03(m_parent.m_lc, Param("sendRecvDuration", reqReport.sendRecvDuration));
if (NULL == filesToRecallList.get()) {
if (req.lastCall) { if (NULL == filesToRecallList.get()) {
_this.m_lc.log(LOG_INFO,"No more file to recall: triggering the end of session.\n"); if (req.lastCall) {
_this.m_tapeReader.finish(); m_parent.m_lc.log(LOG_INFO,"No more file to recall: triggering the end of session.\n");
_this.m_diskWriter.finish(); m_parent.signalEndDataMovement();
break; break;
} else {
m_parent.m_lc.log(LOG_INFO,"In RecallJobInjector::WorkerThread::run(): got empty list, but not last call. NoOp.\n");
}
} else { } else {
_this.m_lc.log(LOG_INFO,"In RecallJobInjector::WorkerThread::run(): got empty list, but not last call. NoOp.\n"); std::vector<tapegateway::FileToRecallStruct*>& jobs= filesToRecallList->filesToRecall();
m_parent.injectBulkRecalls(jobs);
} }
} else { } // end of while(1)
std::vector<tapegateway::FileToRecallStruct*>& jobs= filesToRecallList->filesToRecall(); } //end of try
_this.injectBulkRecalls(jobs); catch(const castor::exception::Exception& ex){
} //we end up there because we could not talk to the client
} // end of while(1) log::ScopedParamContainer container( m_parent.m_lc);
container.add("exception code",ex.code())
.add("exception message",ex.getMessageValue());
m_parent.m_lc.logBacktrace(LOG_ERR,ex.backtrace());
m_parent.m_lc.log(LOG_ERR,"In RecallJobInjector::WorkerThread::run(): "
"could not retrieve a list of file to recall. End of session");
m_parent.signalEndDataMovement();
m_parent.deleteAllTasks();
}
//------------- //-------------
_this.m_lc.log(LOG_DEBUG, "Finishing RecallTaskInjector thread"); m_parent.m_lc.log(LOG_DEBUG, "Finishing RecallTaskInjector thread");
/* We want to finish at the first lastCall we encounter. /* We want to finish at the first lastCall we encounter.
* But even after sending finish() to m_diskWriter and to m_tapeReader, * But even after sending finish() to m_diskWriter and to m_tapeReader,
* m_diskWriter might still want some more task (the threshold could be crossed), * m_diskWriter might still want some more task (the threshold could be crossed),
* so we discard everything that might still be in the queue * so we discard everything that might still be in the queue
*/ */
if(_this.m_queue.size()>0) { if(m_parent.m_queue.size()>0) {
bool stillReading =true; bool stillReading =true;
while(stillReading) { while(stillReading) {
Request req = _this.m_queue.pop(); Request req = m_parent.m_queue.pop();
if (req.end){ if (req.end){
stillReading = false; stillReading = false;
} }
LogContext::ScopedParam sp(_this.m_lc, Param("lastCall", req.lastCall)); LogContext::ScopedParam sp(m_parent.m_lc, Param("lastCall", req.lastCall));
_this.m_lc.log(LOG_INFO,"In RecallJobInjector::WorkerThread::run(): popping extra request"); m_parent.m_lc.log(LOG_INFO,"In RecallJobInjector::WorkerThread::run(): popping extra request");
} }
} }
} }
......
...@@ -110,6 +110,16 @@ public: ...@@ -110,6 +110,16 @@ public:
*/ */
void startThreads(); void startThreads();
private: private:
/**
* It will signal to the disk read thread pool, tape write single thread
* and to the mem manager they have to stop their threads(s)
*/
void signalEndDataMovement();
/**
* It will delete all remaining tasks
*/
void deleteAllTasks();
/** /**
* Create all the tape-read and write-disk tasks for set of files to retrieve * Create all the tape-read and write-disk tasks for set of files to retrieve
...@@ -149,10 +159,10 @@ private: ...@@ -149,10 +159,10 @@ private:
class WorkerThread: public castor::tape::threading::Thread { class WorkerThread: public castor::tape::threading::Thread {
public: public:
WorkerThread(RecallTaskInjector & rji): _this(rji) {} WorkerThread(RecallTaskInjector & rji): m_parent(rji) {}
virtual void run(); virtual void run();
private: private:
RecallTaskInjector & _this; RecallTaskInjector & m_parent;
} m_thread; } m_thread;
///The memory manager for accessing memory blocks. ///The memory manager for accessing memory blocks.
RecallMemoryManager & m_memManager; RecallMemoryManager & m_memManager;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment