示例#1
0
        /// <inheritdoc />
        public IEnumerable <int> Handle(FindErrorMessagesToDeleteQuery <int> query)
        {
            if (query.Cancellation.IsCancellationRequested)
            {
                return(Enumerable.Empty <int>());
            }

            using (var db = _connectionInformation.GetDatabase())
            {
                //before executing a query, double check that we aren't stopping
                //otherwise, there is a chance that the tables no longer exist in memory mode
                if (query.Cancellation.IsCancellationRequested)
                {
                    return(Enumerable.Empty <int>());
                }

                var col = db.Database.GetCollection <Schema.MetaDataErrorsTable>(_tableNameHelper.MetaDataErrorsName);

                var date    = DateTime.UtcNow.Subtract(_configuration.MessageAge);
                var results = col.Query()
                              .Where(x => x.LastExceptionDate < date)
                              .ToList();

                var data = new List <int>(results.Count);
                foreach (var record in results)
                {
                    data.Add(record.QueueId);
                }

                return(data);
            }
        }
示例#2
0
        /// <inheritdoc />
        public long Handle(ResetHeartBeatCommand <int> inputCommand)
        {
            using (var db = _connectionInformation.GetDatabase())
            {
                db.Database.BeginTrans();
                try
                {
                    var col = db.Database.GetCollection <Schema.MetaDataTable>(_tableNameHelper.MetaDataName);

                    var results = col.Query()
                                  .Where(x => x.Status == QueueStatuses.Processing)
                                  .Where(x => x.HeartBeat != null && x.HeartBeat.Value == inputCommand.MessageReset.HeartBeat)
                                  .Where(x => x.QueueId == inputCommand.MessageReset.QueueId)
                                  .Limit(1)
                                  .ToList();

                    if (results.Count == 1)
                    {
                        results[0].Status    = QueueStatuses.Waiting;
                        results[0].HeartBeat = null;
                        col.Update(results[0]);
                    }

                    db.Database.Commit();
                    return(results.Count);
                }
                catch
                {
                    db.Database.Rollback();
                    throw;
                }
            }
        }
        /// <inheritdoc />
        public IEnumerable <int> Handle(FindExpiredMessagesToDeleteQuery <int> query)
        {
            if (query.Cancellation.IsCancellationRequested)
            {
                return(Enumerable.Empty <int>());
            }

            using (var db = _connectionInformation.GetDatabase())
            {
                //before executing a query, double check that we aren't stopping
                if (query.Cancellation.IsCancellationRequested)
                {
                    return(Enumerable.Empty <int>());
                }

                var col = db.Database.GetCollection <Schema.MetaDataTable>(_tableNameHelper.MetaDataName);

                var results = col.Query()
                              .Where(x => x.ExpirationTime < DateTime.UtcNow)
                              .ToList();

                var data = new List <int>(results.Count);
                foreach (var record in results)
                {
                    data.Add(record.QueueId);
                }

                return(data);
            }
        }
示例#4
0
        /// <inheritdoc />
        public QueueCreationResult Handle(CreateQueueTablesAndSaveConfigurationCommand <ITable> command)
        {
            //create database and enforce UTC date de-serialization
            using (var db = _connectionInformation.GetDatabase())
            {
                db.Database.Pragma("UTC_DATE", true);


                //create all tables
                foreach (var table in command.Tables)
                {
                    table.Create(_connectionInformation, _options.Value, _tableNameHelper);
                }

                //save configuration
                foreach (var table in command.Tables)
                {
                    if (table is ConfigurationTable configTable)
                    {
                        var col = db.Database.GetCollection <ConfigurationTable>(_tableNameHelper.ConfigurationName);
                        configTable.Configuration = _serializer.ConvertToBytes(_options.Value);
                        col.Insert(configTable);
                        break;
                    }
                }

                return(new QueueCreationResult(QueueCreationStatus.Success));
            }
        }
示例#5
0
        /// <inheritdoc />
        public long Handle(DeleteMessageCommand <int> command)
        {
            using (var db = _connectionInformation.GetDatabase())
            {
                db.Database.BeginTrans();
                try
                {
                    var col    = db.Database.GetCollection(_tableNameHelper.QueueName);
                    var result = col.Delete(command.QueueId);

                    //note - continue in case we have orphaned records, regardless of result.
                    var meta = db.Database.GetCollection <Schema.MetaDataTable>(_tableNameHelper.MetaDataName);
                    meta.DeleteMany(x => x.QueueId == command.QueueId);

                    var status = db.Database.GetCollection <Schema.StatusTable>(_tableNameHelper.StatusName);
                    status.DeleteMany(x => x.QueueId == command.QueueId);

                    var errorTrack = db.Database.GetCollection <Schema.ErrorTrackingTable>(_tableNameHelper.ErrorTrackingName);
                    errorTrack.DeleteMany(x => x.QueueId == command.QueueId);

                    var metaErrors = db.Database.GetCollection <Schema.MetaDataErrorsTable>(_tableNameHelper.MetaDataErrorsName);
                    metaErrors.DeleteMany(x => x.QueueId == command.QueueId);

                    db.Database.Commit();
                    return(result ? 1 : 0);
                }
                catch
                {
                    db.Database.Rollback();
                    throw;
                }
            }
        }
        /// <inheritdoc />
        public DateTime?Handle(SendHeartBeatCommand <int> command)
        {
            using (var db = _connectionInformation.GetDatabase())
            {
                db.Database.BeginTrans();
                try
                {
                    var col = db.Database.GetCollection <Schema.MetaDataTable>(_tableNameHelper.MetaDataName);

                    var results = col.Query()
                                  .Where(x => x.QueueId == command.QueueId)
                                  .Limit(1)
                                  .ToList();

                    DateTime?date = null;
                    if (results.Count == 1)
                    {
                        var record = results[0];
                        date             = DateTime.UtcNow;
                        record.HeartBeat = date;
                        col.Update(record);
                    }

                    db.Database.Commit();
                    return(date);
                }
                catch
                {
                    db.Database.Rollback();
                    throw;
                }
            }
        }
        /// <inheritdoc />
        public bool Create(LiteDbConnectionManager connection, LiteDbMessageQueueTransportOptions options,
                           TableNameHelper helper)
        {
            using (var db = connection.GetDatabase())
            {
                var col = db.Database.GetCollection <MetaDataTable>(helper.MetaDataName);

                col.EnsureIndex(x => x.Id);
                col.EnsureIndex(x => x.QueueId, true);

                if (options.EnableStatus)
                {
                    col.EnsureIndex(x => x.Status);
                }
                if (options.EnableMessageExpiration)
                {
                    col.EnsureIndex(x => x.ExpirationTime);
                }
                if (options.EnableHeartBeat)
                {
                    col.EnsureIndex(x => x.HeartBeat);
                }
                if (options.EnableRoute)
                {
                    col.EnsureIndex(x => x.Route);
                }

                return(true);
            }
        }
        /// <inheritdoc />
        public bool Create(LiteDbConnectionManager connection, LiteDbMessageQueueTransportOptions options, TableNameHelper helper)
        {
            var db = connection.GetDatabase();
            {
                var col = db.Database.GetCollection <QueueTable>(helper.QueueName);

                //indexed by Id
                col.EnsureIndex(x => x.Id);

                return(true);
            }
        }
示例#9
0
        /// <inheritdoc />
        public bool Create(LiteDbConnectionManager connection, LiteDbMessageQueueTransportOptions options,
                           TableNameHelper helper)
        {
            using (var db = connection.GetDatabase())
            {
                var col = db.Database.GetCollection <ErrorTrackingTable>(helper.ErrorTrackingName);

                col.EnsureIndex(x => x.Id);
                col.EnsureIndex(x => x.QueueId, false); //multiple exceptions per record are possible

                return(true);
            }
        }
示例#10
0
        /// <inheritdoc />
        public bool Create(LiteDbConnectionManager connection, LiteDbMessageQueueTransportOptions options,
                           TableNameHelper helper)
        {
            using (var db = connection.GetDatabase())
            {
                var col = db.Database.GetCollection <MetaDataErrorsTable>(helper.MetaDataErrorsName);

                col.EnsureIndex(x => x.Id);
                col.EnsureIndex(x => x.QueueId, true);

                return(true);
            }
        }
        /// <inheritdoc />
        public QueueRemoveResult Handle(DeleteQueueTablesCommand inputCommand)
        {
            using (var db = _connectionInformation.GetDatabase())
            {
                var dbs    = _tableNameHelper.Tables;
                var delete = db.Database.GetCollectionNames().Where(database => dbs.Contains(database)).ToList();
                foreach (var toDelete in delete)
                {
                    db.Database.DropCollection(toDelete);
                }

                return(new QueueRemoveResult(QueueRemoveStatus.Success));
            }
        }
        /// <inheritdoc />
        public IEnumerable <MessageToReset <int> > Handle(FindMessagesToResetByHeartBeatQuery <int> query)
        {
            if (query.Cancellation.IsCancellationRequested)
            {
                return(Enumerable.Empty <MessageToReset <int> >());
            }

            using (var db = _connectionInformation.GetDatabase())
            {
                //before executing a query, double check that we aren't stopping
                //otherwise, there is a chance that the tables no longer exist in memory mode
                if (query.Cancellation.IsCancellationRequested)
                {
                    return(Enumerable.Empty <MessageToReset <int> >());
                }

                var col  = db.Database.GetCollection <Schema.MetaDataTable>(_tableNameHelper.MetaDataName);
                var date = DateTime.UtcNow.Subtract(_configuration.Time);

                var results = col.Query()
                              .Where(x => x.Status == QueueStatuses.Processing)
                              .Where(x => x.HeartBeat.HasValue && x.HeartBeat.Value < date)
                              .ToList();

                var data  = new List <MessageToReset <int> >(results.Count);
                var queue = db.Database.GetCollection <Schema.QueueTable>(_tableNameHelper.QueueName);
                foreach (var record in results)
                {
                    if (record.HeartBeat.HasValue)
                    {
                        var queueRecord = queue.FindById(record.QueueId);
                        if (queueRecord != null)
                        {
                            var headers =
                                _serialization.InternalSerializer.ConvertBytesTo <IDictionary <string, object> >(
                                    queueRecord
                                    .Headers);
                            var reset = new MessageToReset <int>(record.QueueId, record.HeartBeat.Value,
                                                                 new ReadOnlyDictionary <string, object>(headers));
                            data.Add(reset);
                        }
                    }
                }

                return(data);
            }
        }
示例#13
0
        /// <inheritdoc />
        public DateTimeOffset Handle(GetJobLastKnownEventQuery query)
        {
            using (var db = _connectionInformation.GetDatabase())
            {
                var col = db.Database.GetCollection <Schema.JobsTable>(_tableNameHelper.JobTableName);

                var results = col.Query()
                              .Where(x => x.JobName == query.JobName)
                              .Limit(1)
                              .ToList();

                if (results != null && results.Count == 1)
                {
                    return(results[0].JobEventTime);
                }

                return(default);
        /// <inheritdoc />
        public TTransportOptions Handle(GetQueueOptionsQuery <TTransportOptions> query)
        {
            using (var db = _connectionInformation.GetDatabase())
            {
                if (!_tableExists.Handle(new GetTableExistsQuery(db.Database,
                                                                 _tableNameHelper.ConfigurationName)))
                {
                    return(null);
                }

                var col    = db.Database.GetCollection <ConfigurationTable>(_tableNameHelper.ConfigurationName);
                var result = col.FindOne(global::LiteDB.Query.All());
                return(result?.Configuration != null
                    ? _serializer.ConvertBytesTo <TTransportOptions>(result.Configuration)
                    : null);
            }
        }
示例#15
0
        /// <inheritdoc />
        public int Handle(GetJobIdQuery <int> query)
        {
            using (var db = _connectionInformation.GetDatabase())
            {
                var col = db.Database.GetCollection <Schema.StatusTable>(_tableNameHelper.StatusName);

                var results = col.Query()
                              .Where(x => x.JobName == query.JobName)
                              .Limit(1)
                              .ToList();

                if (results != null && results.Count == 1)
                {
                    return(results[0].QueueId);
                }

                return(default);
        /// <inheritdoc />
        public IDictionary <string, object> Handle(GetHeaderQuery <int> query)
        {
            using (var db = _connectionInformation.GetDatabase())
            {
                var queue = db.Database.GetCollection <Schema.QueueTable>(_tableNameHelper.QueueName);

                var queueRecord = queue.FindById(query.Id);
                if (queueRecord != null)
                {
                    var headers =
                        _serialization.InternalSerializer.ConvertBytesTo <IDictionary <string, object> >(queueRecord
                                                                                                         .Headers);
                    return(headers);
                }
            }

            return(null);
        }
示例#17
0
        /// <inheritdoc />
        public Dictionary <string, int> Handle(GetMessageErrorsQuery <int> query)
        {
            var returnData = new Dictionary <string, int>();

            using (var db = _connectionInformation.GetDatabase())
            {
                var col = db.Database.GetCollection <Schema.ErrorTrackingTable>(_tableNameHelper.ErrorTrackingName);

                var results = col.Query()
                              .Where(x => x.QueueId.Equals(query.QueueId))
                              .ToList();

                foreach (var record in results)
                {
                    returnData.Add(record.ExceptionType, record.RetryCount);
                }

                return(returnData);
            }
        }
示例#18
0
        /// <inheritdoc />
        public int Handle(GetErrorRetryCountQuery <int> query)
        {
            using (var db = _connectionInformation.GetDatabase())
            {
                var col = db.Database.GetCollection <Schema.ErrorTrackingTable>(_tableNameHelper.ErrorTrackingName);

                var results = col.Query()
                              .Where(x => x.QueueId.Equals(query.QueueId))
                              .Where(x => x.ExceptionType == query.ExceptionType)
                              .Limit(1)
                              .ToList();

                if (results != null && results.Count == 1)
                {
                    var record = results[0];
                    return(record.RetryCount);
                }
            }

            return(0);
        }
        /// <inheritdoc />
        public void Handle(SetErrorCountCommand <int> command)
        {
            using (var db = _connectionInformation.GetDatabase())
            {
                db.Database.BeginTrans();
                try
                {
                    var meta    = db.Database.GetCollection <Schema.ErrorTrackingTable>(_tableNameHelper.ErrorTrackingName);
                    var results = meta.Query()
                                  .Where(x => x.QueueId == command.QueueId)
                                  .Where(x => x.ExceptionType == command.ExceptionType)
                                  .Limit(1)
                                  .ToList();

                    if (results != null && results.Count == 1)
                    {
                        //update
                        results[0].RetryCount = results[0].RetryCount + 1;
                        meta.Update(results[0]);
                    }
                    else
                    {
                        var record = new Schema.ErrorTrackingTable()
                        {
                            QueueId       = command.QueueId,
                            ExceptionType = command.ExceptionType,
                            RetryCount    = 1
                        };
                        meta.Insert(record);
                    }

                    db.Database.Commit();
                }
                catch
                {
                    db.Database.Rollback();
                    throw;
                }
            }
        }
        /// <summary>
        /// Handles the specified query.
        /// </summary>
        /// <param name="query">The query.</param>
        /// <returns></returns>
        public IReceivedMessageInternal Handle(ReceiveMessageQuery query)
        {
            if (!_databaseExists.Exists())
            {
                return(null);
            }

            //ensure created
            if (!_options.IsValueCreated)
            {
                _options.Value.ValidConfiguration();
            }

            using (var db = _connectionInformation.GetDatabase())
            {
                lock (Reader)                 //we have to enforce a single de-queue action per process, as BeginTrans does not block in direct or memory mode
                {
                    db.Database.BeginTrans(); //will block in shared mode, but not direct or memory
                    try
                    {
                        var record = DequeueRecord(query, db.Database);
                        if (record != null)
                        {
                            return(_messageDeQueue.HandleMessage(record.Item1, record.Item2.QueueId,
                                                                 record.Item2.CorrelationId));
                        }
                    }
                    finally
                    {
                        db.Database.Commit();
                    }
                }
            }

            return(null);
        }
示例#21
0
        /// <inheritdoc />
        public void Handle(MoveRecordToErrorQueueCommand <int> command)
        {
            using (var db = _connectionInformation.GetDatabase())
            {
                bool delete = false;
                db.Database.BeginTrans();
                try
                {
                    var meta    = db.Database.GetCollection <MetaDataTable>(_tableNameHelper.MetaDataName);
                    var results = meta.Query()
                                  .Where(x => x.QueueId == command.QueueId)
                                  .ToList();

                    if (results != null && results.Count == 1)
                    {
                        //move record to error table
                        var errorRecord = new MetaDataErrorsTable()
                        {
                            LastExceptionDate = DateTime.UtcNow,
                            LastException     = command.Exception.ToString(),
                            QueueId           = results[0].QueueId,
                            Status            = QueueStatuses.Error,
                            CorrelationId     = results[0].CorrelationId,
                            HeartBeat         = results[0].HeartBeat,
                            ExpirationTime    = results[0].ExpirationTime,
                            QueueProcessTime  = results[0].QueueProcessTime,
                            QueuedDateTime    = results[0].QueuedDateTime,
                            Route             = results[0].Route
                        };

                        var errorCol =
                            db.Database.GetCollection <MetaDataErrorsTable>(_tableNameHelper.MetaDataErrorsName);
                        errorCol.Insert(errorRecord);

                        //delete record from metadata table
                        delete = meta.Delete(results[0].Id);

                        //update status table
                        if (_options.Value.EnableStatusTable)
                        {
                            var colStatus     = db.Database.GetCollection <StatusTable>(_tableNameHelper.StatusName);
                            var resultsStatus = colStatus.Query()
                                                .Where(x => x.QueueId == command.QueueId)
                                                .ToList();

                            if (resultsStatus != null && resultsStatus.Count == 1)
                            {
                                resultsStatus[0].Status = QueueStatuses.Error;
                                colStatus.Update(resultsStatus[0]);
                            }
                        }
                    }

                    if (delete)
                    {
                        db.Database.Commit();
                    }
                    else
                    {
                        db.Database.Rollback();
                    }
                }
                catch
                {
                    db.Database.Rollback();
                    throw;
                }
            }
        }
示例#22
0
        /// <summary>
        /// Handles the specified rollback command.
        /// </summary>
        /// <param name="rollBackCommand">The rollBackCommand.</param>
        public void Handle(RollbackMessageCommand <int> rollBackCommand)
        {
            if (!_databaseExists.Exists())
            {
                return;
            }

            using (var db = _connectionInformation.GetDatabase())
            {
                db.Database.BeginTrans();
                try
                {
                    var col = db.Database.GetCollection <Schema.MetaDataTable>(_tableNameHelper.MetaDataName);

                    var results2 = col.Query()
                                   .Where(x => x.QueueId.Equals(rollBackCommand.QueueId))
                                   .Limit(1)
                                   .ToList();

                    if (results2 != null && results2.Count == 1)
                    {
                        var record = results2[0];
                        if (record != null)
                        {
                            var process = true;
                            if (rollBackCommand.LastHeartBeat.HasValue)
                            {
                                //heartbeat must match
                                if (TrimMilliseconds(record.HeartBeat) !=
                                    TrimMilliseconds(rollBackCommand.LastHeartBeat))
                                {
                                    process = false;
                                }
                            }

                            if (process)
                            {
                                if (_options.Value.EnableDelayedProcessing &&
                                    rollBackCommand.IncreaseQueueDelay.HasValue)
                                {
                                    var dtUtcDate          = _getUtcDateQuery.Create().GetCurrentUtcDate();
                                    var dtUtcDateIncreased = dtUtcDate.Add(rollBackCommand.IncreaseQueueDelay.Value);

                                    //move to future
                                    record.QueueProcessTime = dtUtcDateIncreased;
                                }

                                if (_options.Value.EnableHeartBeat)
                                {
                                    record.HeartBeat = null;
                                }

                                record.Status = QueueStatuses.Waiting;

                                col.Update(record);

                                if (_options.Value.EnableStatusTable)
                                {
                                    var statusCol = db.Database.GetCollection <Schema.StatusTable>(_tableNameHelper.StatusName);
                                    var results   = statusCol.Query()
                                                    .Where(x => x.QueueId.Equals(record.QueueId))
                                                    .Limit(1)
                                                    .ToList();

                                    if (results.Count == 1)
                                    {
                                        var statusRecord = results[0];
                                        statusRecord.Status = record.Status;
                                        statusCol.Update(statusRecord);
                                    }
                                }
                            }
                        }
                    }

                    db.Database.Commit();
                }
                catch
                {
                    db.Database.Rollback();
                    throw;
                }
            }
        }
        /// <summary>
        /// Handles the specified command.
        /// </summary>
        /// <param name="commandSend">The command.</param>
        /// <returns></returns>
        /// <exception cref="DotNetWorkQueueException">Failed to insert record - the ID of the new record returned by SQLite was 0</exception>
        public async Task <int> HandleAsync(SendMessageCommand commandSend)
        {
            return(await Task.Run(() => //hack until litedb adds async methods
            {
                if (!_databaseExists.Exists())
                {
                    return 0;
                }

                if (!_messageExpirationEnabled.HasValue)
                {
                    _messageExpirationEnabled = _options.Value.EnableMessageExpiration;
                }


                TimeSpan?expiration = null;
                if (_messageExpirationEnabled.Value)
                {
                    expiration = MessageExpiration.GetExpiration(commandSend, data => data.GetExpiration());
                }

                var jobName = _jobSchedulerMetaData.GetJobName(commandSend.MessageData);
                var scheduledTime = DateTimeOffset.MinValue;
                var eventTime = DateTimeOffset.MinValue;
                if (!string.IsNullOrWhiteSpace(jobName))
                {
                    scheduledTime = _jobSchedulerMetaData.GetScheduledTime(commandSend.MessageData);
                    eventTime = _jobSchedulerMetaData.GetEventTime(commandSend.MessageData);
                }

                int id = 0;
                using (var db = _connectionInformation.GetDatabase())
                {
                    lock (Locker) //we need to block due to jobs
                    {
                        try
                        {
                            db.Database.BeginTrans(); //only blocks on shared connections
                            if (string.IsNullOrWhiteSpace(jobName) || _jobExistsHandler.Handle(
                                    new DoesJobExistQuery(jobName, scheduledTime, db.Database)) ==
                                QueueStatuses.NotQueued)
                            {
                                var serialization =
                                    _serializer.Serializer.MessageToBytes(
                                        new MessageBody {
                                    Body = commandSend.MessageToSend.Body
                                },
                                        commandSend.MessageToSend.Headers);

                                //create queue
                                var queueData = new LiteDb.Schema.QueueTable()
                                {
                                    Body = serialization.Output
                                };
                                commandSend.MessageToSend.SetHeader(_headers.StandardHeaders.MessageInterceptorGraph,
                                                                    serialization.Graph);
                                queueData.Headers =
                                    _serializer.InternalSerializer.ConvertToBytes(commandSend.MessageToSend.Headers);

                                var col = db.Database.GetCollection <QueueTable>(_tableNameHelper.QueueName);
                                id = col.Insert(queueData).AsInt32;

                                //create metadata
                                var metaData = new LiteDb.Schema.MetaDataTable
                                {
                                    QueueId = id,
                                    CorrelationId = (Guid)commandSend.MessageData.CorrelationId.Id.Value,
                                    QueuedDateTime = DateTime.UtcNow
                                };

                                if (!string.IsNullOrWhiteSpace(jobName))
                                {
                                    metaData.QueueProcessTime = scheduledTime.UtcDateTime;
                                }
                                else if (_options.Value.EnableDelayedProcessing)
                                {
                                    var delay = commandSend.MessageData.GetDelay();
                                    if (delay.HasValue)
                                    {
                                        metaData.QueueProcessTime = DateTime.UtcNow.Add(delay.Value);
                                    }
                                }

                                if (_options.Value.EnableMessageExpiration && expiration.HasValue)
                                {
                                    metaData.ExpirationTime = DateTime.UtcNow.Add(expiration.Value);
                                }

                                if (_options.Value.EnableStatus)
                                {
                                    metaData.Status = QueueStatuses.Waiting;
                                }

                                if (_options.Value.EnableRoute)
                                {
                                    metaData.Route = commandSend.MessageData.Route;
                                }

                                var colMeta = db.Database.GetCollection <MetaDataTable>(_tableNameHelper.MetaDataName);
                                colMeta.Insert(metaData);

                                //create status table record
                                if (_options.Value.EnableStatusTable || !string.IsNullOrWhiteSpace(jobName))
                                {
                                    var statusData = new LiteDb.Schema.StatusTable()
                                    {
                                        Status = metaData.Status,
                                        CorrelationId = metaData.CorrelationId,
                                        QueueId = id
                                    };
                                    if (!string.IsNullOrWhiteSpace(jobName))
                                    {
                                        statusData.JobName = jobName;
                                    }
                                    var colStatus = db.Database.GetCollection <StatusTable>(_tableNameHelper.StatusName);
                                    colStatus.Insert(statusData);
                                }

                                //job name
                                if (!string.IsNullOrWhiteSpace(jobName))
                                {
                                    _sendJobStatus.Handle(new SetJobLastKnownEventCommand(jobName, eventTime,
                                                                                          scheduledTime, db.Database));
                                }
                            }
                            else
                            {
                                throw new DotNetWorkQueueException(
                                    "Failed to insert record - the job has already been queued or processed");
                            }

                            db.Database.Commit();
                        }
                        catch
                        {
                            db.Database.Rollback();
                            throw;
                        }
                    }
                }

                return id;
            }));
        }