1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
|
/******************************************************************************
This source file is part of the MoleQueue project.
Copyright 2012 Kitware, Inc.
This source code is released under the New BSD License, (the "License").
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.
******************************************************************************/
#ifndef MOLEQUEUE_QUEUE_H
#define MOLEQUEUE_QUEUE_H
#include <QtCore/QObject>
#include "job.h"
#include "idtypeutils.h"
#include <QtCore/QMap>
#include <QtCore/QList>
#include <QtCore/QMetaType>
#include <QtCore/QPointer>
#include <QtCore/QStringList>
class QJsonObject;
namespace MoleQueue
{
class AbstractQueueSettingsWidget;
class Job;
class Program;
class QueueManager;
class Server;
/**
* @class Queue queue.h <molequeue/queue.h>
* @brief Abstract interface for queuing systems.
* @author Marcus D. Hanwell, David C. Lonie
*
* The Queue interface defines interactions with a distributed resource
* management system, such as job submission and job status updates. Each
* Queue object manages a set of Program instances, which contain information
* about the related task of actually running an executable to do work.
*/
class Queue : public QObject
{
Q_OBJECT
protected:
/**
* Protected constructor. Use QueueManager:::addQueue() method to create new
* Queue objects.
*/
explicit Queue(const QString &queueName = "Undefined",
QueueManager *parentManager = 0);
public:
~Queue();
/// @return The parent Server
Server *server() { return m_server; }
/// @return The parent Server
const Server *server() const { return m_server; }
/// @return The parent QueueManager
QueueManager *queueManager() { return m_queueManager; }
/// @return The parent Server
const QueueManager *queueManager() const { return m_queueManager; }
/**
* Set the name of the queue. This should be unique, and will be used in the
* GUI to refer to this queue.
*/
virtual void setName(const QString &newName)
{
if (newName != m_name) {
QString oldName = m_name;
m_name = newName;
emit nameChanged(newName, oldName);
}
}
/** Get the name of the queue. */
QString name() const { return m_name; }
/**
* Returns the type of the queue as a string.
*/
virtual QString typeName() const { return "Unknown"; }
/**
* Read settings for the queue, done early on at startup.
* @param filePath Path to the .mqq file with the queue settings.
*
* This method calls readJsonSettings to perform the actual setting of
* state information. Subclasses should reimplement that method.
*/
bool readSettings(const QString &filePath);
/**
* Write settings for the queue, done just before closing the server.
* The settings are written to
* [server's local working directory]/config/queues/[queuename].mqq
*
* This method calls writeJsonSettings to perform the actual collection of
* state information. Subclasses should reimplement that method.
*/
bool writeSettings() const;
/**
* Write this Queue's configuration to the .mqq file @a fileName.
* Sensitive data (such as usernames, etc) and mutatable state data (like
* current jobs) are not written, see writeSettings() if these are needed.
* @param includePrograms Export this queue's programs as well. Default: true
*
* This method calls writeJsonSettings to perform the actual collection of
* state information. Subclasses should reimplement that method.
*/
bool exportSettings(const QString &fileName,
bool includePrograms = true) const;
/**
* Set this Queue's configuration using the the .mqq file @a fileName.
* Sensitive data (such as usernames, etc) and mutatable state data (like
* current jobs) are not read, see readSettings() if these are needed.
* @param includePrograms Import any programs contained in the importer.
* Default: true
*
* This method calls readJsonSettings to perform the actual setting of
* state information. Subclasses should reimplement that method.
*/
bool importSettings(const QString &fileName, bool includePrograms = true);
/**
* @param mqqFile Filename of the mqq (MoleQueue Queue) file.
* @return Return the type of queue that is stored in the .mqq file.
*/
static QString queueTypeFromFile(const QString &mqqFile);
/**
* @return The name of the persistant state file used to store this Queue's
* configuration.
*/
QString stateFileName() const;
/**
* @brief writeJsonSettings Write the queue's internal state into a JSON
* object.
* @param value Target JSON object.
* @param exportOnly If true, instance specific information (e.g. currently
* running jobs, login details, etc) is omitted.
* @param includePrograms Whether or not to include the Queue's program
* configurations.
* @return True on success, false on failure.
*/
virtual bool writeJsonSettings(QJsonObject &value, bool exportOnly,
bool includePrograms) const;
/**
* @brief readJsonSettings Initialize the queue's internal state from a JSON
* object.
* @param value Source JSON object.
* @param importOnly If true, instance specific information (e.g. currently
* running jobs, login details, etc) is ignored.
* @param includePrograms Whether or not to include the Queue's program
* configurations.
* @return True on success, false on failure.
*
* @note When reimplementing this method, verify and parse the Json object
* into temporary variables, then call the base class implementation and only
* modify the queue if the call returns true.
*/
virtual bool readJsonSettings(const QJsonObject &value, bool importOnly,
bool includePrograms);
/**
* Returns a widget that can be used to configure the settings for the
* queue.
*/
virtual AbstractQueueSettingsWidget* settingsWidget();
/**
* Add a new program to the queue. Program names must be unique in each
* queue, as they are used to specify which program will be used.
* @note This Queue instance will take ownership and reparent @a newProgram.
* @param program The program to be added to the queue.
* @param replace Defaults to false, if true replace any program with the
* same name in this queue.
* @return True on success, false on failure.
*/
bool addProgram(Program *newProgram, bool replace = false);
/**
* Attempt to remove a program from the queue. The program name is used
* as the criteria to decice which object to remove.
* @param program The program to be removed from the queue.
* @return True on success, false on failure.
*/
bool removeProgram(Program *programToRemove);
/**
* Attempt to remove a program from the queue. The program name is used
* as the criteria to decide which object to remove.
* @param name The name of the program to be removed from the queue.
* @return True on success, false on failure.
*/
bool removeProgram(const QString &programName);
/**
* Retrieve the program object associated with the supplied name.
* @param name The name of the program.
* @return The Program object, a null pointer is returned if the
* requested program is not in this queue.
*/
Program* lookupProgram(const QString &programName) const
{
return m_programs.value(programName, NULL);
}
/**
* @return A list of program names available through this queue.
*/
QStringList programNames() const
{
return m_programs.keys();
}
/**
* @return A list of the available Program objects.
*/
QList<Program *> programs() const
{
return m_programs.values();
}
/**
* @return The number of programs belonging to this Queue.
*/
int numPrograms() const
{
return m_programs.size();
}
/**
* @return A string containing a template for the launcher script. For remote
* queues, this will be a batch script for the queuing system, for local
* queues this will be a shell script (unix) or batch script (windows).
*
* It should contain the token "$$programExecution$$", which will be replaced
* with program-specific launch details.
*/
virtual QString launchTemplate() const { return m_launchTemplate; }
/**
* @return The filename for the launcher script. For remote
* queues, this will be a batch script for the queuing system, for local
* queues this will be a shell script (unix) or batch script (windows).
*/
QString launchScriptName() const { return m_launchScriptName; }
/**
* @param moleQueueId MoleQueue id of Job of interest.
* @return The number of time the job has failed if it has encountered an
* error and is being retried. 0 if the job has not encountered an error, or
* has exceeded three retries.
*/
int jobFailureCount(IdType moleQueueId) const
{
return m_failureTracker.value(moleQueueId, 0);
}
/**
* @brief replaceKeywords Replace $$keywords$$ in @a launchScript
* with queue/job specific values.
* @param launchScript Launch script to complete.
* @param job Job data to use.
*/
virtual void replaceKeywords(QString & launchScript,
const Job &job,
bool addNewline = true);
/// For queue creation
friend class MoleQueue::QueueManager;
signals:
/**
* Emitted when a new program is added to the Queue.
* @param name Name of the program.
* @param program Pointer to the newly added Program object.
*/
void programAdded(const QString &name, MoleQueue::Program *program);
/**
* Emitted when a program is removed from the queue.
* @param name Name of the program
* @param program Pointer to the removed Program object.
* @warning The @program pointer should not be dereferenced, as this signal
* is often associated with program deletion.
*/
void programRemoved(const QString &name, MoleQueue::Program *program);
/**
* @brief programRenamed Emitted when a program is renamed.
*/
void programRenamed(const QString &newName, Program *prog,
const QString &oldName);
/**
* Emitted when the name of the queue is changed.
*/
void nameChanged(const QString &newName, const QString &oldName);
public slots:
/**
* Writes input files and submits a new job to the queue.
* @param job Job to submit.
* @return True on success, false on failure.
* @sa jobSubmitted
*/
virtual bool submitJob(MoleQueue::Job job) = 0;
/**
* @brief killJob Stop the job and remove from the queue. Set the JobState to
* Canceled.
* @param job Job to kill.
*/
virtual void killJob(MoleQueue::Job job) = 0;
/**
* Update the launch script template.
* @param script The new launch template.
* @sa launchTemplate
*/
virtual void setLaunchTemplate(const QString &script)
{
m_launchTemplate = script;
}
/**
* Update the launch script name.
* @param scriptName The new launch script name.
* @sa launchTemplate
* @sa launchScript
*/
virtual void setLaunchScriptName(const QString &scriptName)
{
m_launchScriptName = scriptName;
}
protected slots:
/**
* Called when the JobManager::jobAboutToBeRemoved signal is emitted to
* remove any internal references to the job. Subclasses should reimplement
* if they hold any state about owned jobs.
*/
virtual void jobAboutToBeRemoved(const MoleQueue::Job &job);
/**
* Update internal data structures when the name of a program changes.
*/
void programNameChanged(const QString &newName, const QString &oldName);
/**
* Delete the local working directory of @a Job.
*/
void cleanLocalDirectory(const MoleQueue::Job &job);
protected:
/// Write the input files for @a job to the local working directory.
bool writeInputFiles(const Job &job);
/**
* @brief addJobFailure Call this when a job encounters a problem but will be
* retried (e.g. a possible networking failure). The failure will be recorded
* and the return value will indicate whether to retry the job or not. If this
* function returns true, the job has failed less than 3 times and an attempt
* should be made to retry. If it returns false, the job has exceeded the
* maximum number of retries and should be aborted. The failure count will be
* reset and an error will be logged if the maximum retries are exceeded.
* @param moleQueueId
* @return True if the job should be retried, false otherwise.
* @see jobFailureCount
* @see clearJobFailures
*/
bool addJobFailure(IdType moleQueueId);
/**
* @brief clearJobFailures Remove all recorded job failures for a job. This
* does not necessarily mean that the job is successful, but that it is no
* longer being retried.
* @param moleQueueId MoleQueue id of job
* @see addJobFailure
* @see jobFailureCount
*/
void clearJobFailures(IdType moleQueueId)
{
m_failureTracker.remove(moleQueueId);
}
QueueManager *m_queueManager;
Server *m_server;
QString m_name;
QString m_launchTemplate;
QString m_launchScriptName;
QMap<QString, Program *> m_programs;
/// Lookup table for jobs that are using this Queue. Maps JobId to MoleQueueId.
QMap<IdType, IdType> m_jobs;
/// Keeps track of the number of times a job has failed (MoleQueueId to
/// #failures). Once a job fails three times, it will no longer retry.
QMap<IdType, int> m_failureTracker;
private:
/// Private helper function
bool writeJsonSettingsToFile(const QString &filename, bool exportOnly,
bool includePrograms) const;
/// Private helper function
bool readJsonSettingsFromFile(const QString &filename, bool importOnly,
bool includePrograms);
};
} // End namespace
Q_DECLARE_METATYPE(MoleQueue::Queue*)
Q_DECLARE_METATYPE(const MoleQueue::Queue*)
#endif // MOLEQUEUE_QUEUE_H
|