/// <inheritdoc />
        public List <ResetHeartBeatOutput> Reset(CancellationToken cancelToken)
        {
            if (!_configuration.HeartBeat.Enabled)
            {
                return(new List <ResetHeartBeatOutput>(0));
            }

            if (string.IsNullOrEmpty(_configuration.TransportConfiguration.ConnectionInfo.ConnectionString))
            {
                return(new List <ResetHeartBeatOutput>(0));
            }

            List <ResetHeartBeatOutput> returnData = new List <ResetHeartBeatOutput>();
            var      query   = new FindMessagesToResetByHeartBeatQuery <T>(cancelToken);
            DateTime start   = _getTime.GetCurrentUtcDate();
            var      results = _queryHandler.Handle(query);
            DateTime end     = _getTime.GetCurrentUtcDate();

            foreach (var result in results)
            {
                var id          = new MessageQueueId <T>(result.QueueId);
                var command     = new ResetHeartBeatCommand <T>(result);
                var resetResult = _commandHandler.Handle(command);
                if (resetResult <= 0)
                {
                    continue;
                }
                var data = new ResetHeartBeatOutput(id, result.Headers, start, end);
                returnData.Add(data);
            }
            return(returnData);
        }
        internal void BuildCommand(IDbCommand selectCommand, CommandString commandString,
                                   SqLiteMessageQueueTransportOptions options, List <string> routes)
        {
            selectCommand.CommandText = commandString.CommandText;

            var paramDate = selectCommand.CreateParameter();

            paramDate.ParameterName = "@CurrentDateTime";
            paramDate.DbType        = DbType.Int64;
            paramDate.Value         = _getTime.GetCurrentUtcDate().Ticks;
            selectCommand.Parameters.Add(paramDate);

            if (options.EnableRoute && routes != null && routes.Count > 0)
            {
                var routeCounter = 1;
                foreach (var route in routes)
                {
                    var param = selectCommand.CreateParameter();
                    param.ParameterName = "@Route" + routeCounter;
                    param.DbType        = DbType.AnsiString;
                    param.Value         = route;
                    selectCommand.Parameters.Add(param);
                    routeCounter++;
                }
            }
        }
        /// <inheritdoc />
        public DateTime Handle(SendHeartBeatCommand <long> command, IDbCommand dbCommand, CommandStringTypes commandType)
        {
            dbCommand.CommandText = _commandCache.GetCommand(commandType);

            var param = dbCommand.CreateParameter();

            param.ParameterName = "@QueueID";
            param.Value         = command.QueueId;
            param.DbType        = DbType.Int64;
            dbCommand.Parameters.Add(param);

            param = dbCommand.CreateParameter();
            param.ParameterName = "@Status";
            param.DbType        = DbType.Int32;
            param.Value         = Convert.ToInt16(QueueStatuses.Processing);
            dbCommand.Parameters.Add(param);

            param = dbCommand.CreateParameter();
            param.ParameterName = "@date";
            param.DbType        = DbType.Int64;
            var date = _getTime.GetCurrentUtcDate();

            param.Value = date.Ticks;
            dbCommand.Parameters.Add(param);

            return(date);
        }
Example #4
0
        public void StartSchedule()
        {
            lock (_scheduleLock)
            {
                if (!IsAttached)
                {
                    throw new JobSchedulerException("Cannot start task which is not attached to a scheduler.");
                }

                if (IsScheduleRunning)
                {
                    return;
                }

                var firstEvent     = default(DateTimeOffset);
                var firstEventSet  = false;
                var window         = Window;
                var lastKnownEvent = _queue.LastKnownEvent.Get(Name);
                if (window > TimeSpan.Zero && lastKnownEvent != default)
                {
                    // check if we actually want to run the first event right away
                    var prev = Schedule.Previous();
                    lastKnownEvent = lastKnownEvent.AddSeconds(1); // add a second for good measure
                    if (prev > lastKnownEvent && prev > new DateTimeOffset(_getTime.GetCurrentUtcDate()) - window)
                    {
                        firstEvent    = prev;
                        firstEventSet = true;
                    }
                }

                if (!firstEventSet)
                {
                    firstEvent = Schedule.Next();
                }

                while (firstEvent <= PrevEvent)
                {
                    // we don't want to run the same event twice
                    firstEvent = Schedule.Next(firstEvent);
                }

                NextEvent         = firstEvent;
                IsScheduleRunning = true;
                QueueNextEvent();
            }
        }
Example #5
0
        /// <summary>
        /// Handles the specified query.
        /// </summary>
        /// <param name="query">The query.</param>
        /// <param name="dbCommand">The database command.</param>
        /// <param name="commandType">Type of the command.</param>
        public void Handle(FindExpiredMessagesToDeleteQuery <long> query, IDbCommand dbCommand, CommandStringTypes commandType)
        {
            dbCommand.CommandText = _commandCache.GetCommand(commandType);

            var command = (NpgsqlCommand)dbCommand;

            command.Parameters.Add("@CurrentDate", NpgsqlDbType.Bigint);
            command.Parameters["@CurrentDate"].Value = _getTime.GetCurrentUtcDate().Ticks;
        }
Example #6
0
 internal static SQLiteCommand CreateMetaDataRecord(TimeSpan? delay, TimeSpan expiration, SQLiteConnection connection,
     IMessage message, IAdditionalMessageData data, TableNameHelper tableNameHelper, 
     IHeaders headers, SqLiteMessageQueueTransportOptions options, IGetTime getTime)
 {
     var command = new SQLiteCommand(connection);
     BuildMetaCommand(command, tableNameHelper, headers,
         data, message, 0, options, delay, expiration, getTime.GetCurrentUtcDate());
     return command;
 }
        /// <inheritdoc />
        public void Handle(FindErrorMessagesToDeleteQuery <long> query, IDbCommand dbCommand, CommandStringTypes commandType)
        {
            dbCommand.CommandText = _commandCache.GetCommand(commandType);

            var command = (NpgsqlCommand)dbCommand;

            command.Parameters.Add("@CurrentDate", NpgsqlDbType.Timestamp);
            command.Parameters["@CurrentDate"].Value = _getTime.GetCurrentUtcDate().Subtract(_configuration.MessageAge);
        }
Example #8
0
        internal static IDbCommand CreateMetaDataRecord(TimeSpan?delay, TimeSpan expiration, IDbConnection connection,
                                                        IMessage message, IAdditionalMessageData data, TableNameHelper tableNameHelper,
                                                        IHeaders headers, SqLiteMessageQueueTransportOptions options, IGetTime getTime)
        {
            var command = connection.CreateCommand();

            BuildMetaCommand(command, tableNameHelper, headers,
                             data, message, 0, options, delay, expiration, getTime.GetCurrentUtcDate());
            return(command);
        }
Example #9
0
        /// <inheritdoc />
        public void Handle(FindErrorMessagesToDeleteQuery query, IDbCommand dbCommand, CommandStringTypes commandType)
        {
            dbCommand.CommandText = _commandCache.GetCommand(commandType);

            var param = dbCommand.CreateParameter();

            param.ParameterName = "@CurrentDate";
            param.DbType        = DbType.DateTime;
            param.Value         = _getTime.GetCurrentUtcDate().Subtract(_configuration.MessageAge);
            dbCommand.Parameters.Add(param);
        }
        /// <inheritdoc />
        public void Handle(FindErrorMessagesToDeleteQuery <long> query, IDbCommand dbCommand, CommandStringTypes commandType)
        {
            dbCommand.CommandText = _commandCache.GetCommand(commandType);

            var command = dbCommand;
            var param   = command.CreateParameter();

            param.ParameterName = "@CurrentDateTime";
            param.DbType        = DbType.Int64;
            param.Value         = _getTime.GetCurrentUtcDate().Ticks - _configuration.MessageAge.Ticks;
            command.Parameters.Add(param);
        }
        /// <summary>
        /// Handles the specified query.
        /// </summary>
        /// <param name="query">The query.</param>
        /// <param name="dbCommand">The database command.</param>
        /// <param name="commandType">Type of the command.</param>
        public void Handle(FindMessagesToResetByHeartBeatQuery query, IDbCommand dbCommand, CommandStringTypes commandType)
        {
            dbCommand.CommandText =
                _commandCache.GetCommand(commandType);

            var command = (NpgsqlCommand)dbCommand;

            command.Parameters.Add("@Time", NpgsqlDbType.Bigint);
            var selectTime = _getTime.GetCurrentUtcDate().AddSeconds(_configuration.HeartBeat.Time.TotalSeconds * -1);

            command.Parameters["@time"].Value = selectTime.Ticks;
            command.Parameters.Add("@Status", NpgsqlDbType.Integer);
            command.Parameters["@Status"].Value = Convert.ToInt16(QueueStatuses.Processing);
        }
        /// <summary>
        /// Resets the heartbeat for records outside of the window.
        /// </summary>
        /// <param name="unixTime">The unix time.</param>
        /// <param name="count">The count.</param>
        /// <returns></returns>
        public List <ResetHeartBeatOutput> Execute(long unixTime, int count)
        {
            if (Connection.IsDisposed)
            {
                return(new List <ResetHeartBeatOutput>());
            }

            DateTime start  = _getTime.GetCurrentUtcDate();
            var      result = TryExecute(GetParameters(unixTime, count));
            DateTime end    = _getTime.GetCurrentUtcDate();

            if (result.IsNull)
            {
                return(new List <ResetHeartBeatOutput>(0));
            }
            var ids        = (RedisResult[])result;
            var returnData = new List <ResetHeartBeatOutput>(ids.Length);

            foreach (RedisResult[] id in ids)
            {
                var queueId = (string)id[0];
                var header  = (byte[])id[1];
                IDictionary <string, object> headers = null;
                if (header != null)
                {
                    headers = _serialization.InternalSerializer.ConvertBytesTo <IDictionary <string, object> >(header);
                }

                if (headers != null)
                {
                    returnData.Add(new ResetHeartBeatOutput(new RedisQueueId(queueId), new ReadOnlyDictionary <string, object>(headers), start, end));
                }
                returnData.Add(new ResetHeartBeatOutput(new RedisQueueId(queueId), null, start, end));
            }

            return(returnData);
        }
Example #13
0
        /// <summary>
        /// Handles the specified query.
        /// </summary>
        /// <param name="query">The query.</param>
        /// <param name="dbCommand">The database command.</param>
        /// <param name="commandType">Type of the command.</param>
        public void Handle(FindMessagesToResetByHeartBeatQuery <long> query, IDbCommand dbCommand, CommandStringTypes commandType)
        {
            dbCommand.CommandText =
                _commandCache.GetCommand(commandType);

            var command = dbCommand;

            var param = command.CreateParameter();

            param.ParameterName = "@Time";
            param.DbType        = DbType.Int64;
            param.Value         = _getTime.GetCurrentUtcDate().AddSeconds(_configuration.HeartBeat.Time.TotalSeconds * -1).Ticks;
            command.Parameters.Add(param);

            param = command.CreateParameter();
            param.ParameterName = "@Status";
            param.DbType        = DbType.Int32;
            param.Value         = Convert.ToInt16(QueueStatuses.Processing);
            command.Parameters.Add(param);
        }
        /// <summary>
        /// Handles the specified command.
        /// </summary>
        /// <param name="command">The command.</param>
        /// <param name="dbCommand">The database command.</param>
        /// <param name="commandType">Type of the command.</param>
        public void Handle(MoveRecordToErrorQueueCommand <long> command, IDbCommand dbCommand, CommandStringTypes commandType)
        {
            dbCommand.CommandText = _buildSql.Create();
            var commandSql = dbCommand;

            var param = commandSql.CreateParameter();

            param.ParameterName = "@QueueID";
            param.DbType        = DbType.Int64;
            param.Value         = command.QueueId;
            commandSql.Parameters.Add(param);

            param = commandSql.CreateParameter();
            param.ParameterName = "@LastException";
            param.DbType        = DbType.String;
            param.Value         = command.Exception.ToString();
            commandSql.Parameters.Add(param);

            param = commandSql.CreateParameter();
            param.ParameterName = "@CurrentDateTime";
            param.DbType        = DbType.Int64;
            param.Value         = _getTime.GetCurrentUtcDate().Ticks;
            commandSql.Parameters.Add(param);
        }
Example #15
0
        /// <inheritdoc />
        public async Task <long> HandleAsync(SendMessageCommand commandSend)
        {
            if (!_messageExpirationEnabled.HasValue)
            {
                _messageExpirationEnabled = _options.Value.EnableMessageExpiration;
            }

            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);
            }

            using (var connection = new NpgsqlConnection(_configurationSend.ConnectionInfo.ConnectionString))
            {
                connection.Open();
                using (var trans = connection.BeginTransaction())
                {
                    if (string.IsNullOrWhiteSpace(jobName) || _jobExistsHandler.Handle(new DoesJobExistQuery <NpgsqlConnection, NpgsqlTransaction>(jobName, scheduledTime, connection, trans)) ==
                        QueueStatuses.NotQueued)
                    {
                        using (var command = connection.CreateCommand())
                        {
                            command.CommandText = _commandCache.GetCommand(CommandStringTypes.InsertMessageBody);
                            command.Transaction = trans;
                            var serialization =
                                _serializer.Serializer.MessageToBytes(new MessageBody
                            {
                                Body = commandSend.MessageToSend.Body
                            }, commandSend.MessageToSend.Headers);

                            command.Parameters.Add("@body", NpgsqlDbType.Bytea, -1);
                            command.Parameters["@body"].Value = serialization.Output;

                            commandSend.MessageToSend.SetHeader(_headers.StandardHeaders.MessageInterceptorGraph,
                                                                serialization.Graph);

                            command.Parameters.Add("@headers", NpgsqlDbType.Bytea, -1);
                            command.Parameters["@headers"].Value =
                                _serializer.InternalSerializer.ConvertToBytes(commandSend.MessageToSend.Headers);

                            var id = Convert.ToInt64(await command.ExecuteScalarAsync().ConfigureAwait(false));
                            if (id > 0)
                            {
                                var expiration = TimeSpan.Zero;
                                if (_messageExpirationEnabled.Value)
                                {
                                    expiration = MessageExpiration.GetExpiration(commandSend, data => data.GetExpiration());
                                }

                                await
                                CreateMetaDataRecordAsync(commandSend.MessageData.GetDelay(), expiration, connection,
                                                          id,
                                                          commandSend.MessageToSend, commandSend.MessageData, trans, _getTime.GetCurrentUtcDate()).ConfigureAwait(false);

                                if (_options.Value.EnableStatusTable)
                                {
                                    await
                                    CreateStatusRecordAsync(connection, id, commandSend.MessageToSend,
                                                            commandSend.MessageData, trans).ConfigureAwait(false);
                                }

                                if (!string.IsNullOrWhiteSpace(jobName))
                                {
                                    _sendJobStatus.Handle(new SetJobLastKnownEventCommand <NpgsqlConnection, NpgsqlTransaction>(jobName, eventTime,
                                                                                                                                scheduledTime, connection, trans));
                                }
                            }
                            else
                            {
                                throw new DotNetWorkQueueException(
                                          "Failed to insert record - the ID of the new record returned by the server was 0");
                            }
                            trans.Commit();
                            return(id);
                        }
                    }
                    throw new DotNetWorkQueueException(
                              "Failed to insert record - the job has already been queued or processed");
                }
            }
        }
        /// <summary>
        /// Creates the status record.
        /// </summary>
        /// <param name="connection">The connection.</param>
        /// <param name="message">The message.</param>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        private IDbCommand CreateStatusRecord(IDbConnection connection, IMessage message,
                                              IAdditionalMessageData data)
        {
            var command = connection.CreateCommand();

            SendMessage.BuildStatusCommand(command, _tableNameHelper, _headers, data, message, 0, _options.Value, _getTime.GetCurrentUtcDate());
            return(command);
        }
        /// <inheritdoc />
        public IReceivedMessageInternal Handle(ReceiveMessageQuery <NpgsqlConnection, NpgsqlTransaction> query)
        {
            using (var selectCommand = query.Connection.CreateCommand())
            {
                selectCommand.Transaction = query.Transaction;
                selectCommand.CommandText =
                    ReceiveMessage.GetDeQueueCommand(_commandCache, _tableNameHelper, _options.Value,
                                                     query.Routes);

                selectCommand.Parameters.Add("@CurrentDate", NpgsqlDbType.Bigint);
                selectCommand.Parameters["@CurrentDate"].Value = _getTime.GetCurrentUtcDate().Ticks;

                if (_options.Value.EnableRoute && query.Routes != null && query.Routes.Count > 0)
                {
                    var routeCounter = 1;
                    foreach (var route in query.Routes)
                    {
                        selectCommand.Parameters.Add("@Route" + routeCounter, NpgsqlDbType.Varchar);
                        selectCommand.Parameters["@Route" + routeCounter].Value = route;
                        routeCounter++;
                    }
                }

                using (var reader = selectCommand.ExecuteReader())
                {
                    if (!reader.Read())
                    {
                        return(null);
                    }

                    //load up the message from the DB
                    long   id             = 0;
                    var    correlationId  = Guid.Empty;
                    byte[] headerPayload  = null;
                    byte[] messagePayload = null;
                    try
                    {
                        id             = (long)reader["queueid"];
                        correlationId  = (Guid)reader["CorrelationID"];
                        headerPayload  = (byte[])reader["Headers"];
                        messagePayload = (byte[])reader["body"];

                        var headers =
                            _serialization.InternalSerializer
                            .ConvertBytesTo <IDictionary <string, object> >(headerPayload);
                        var messageGraph =
                            (MessageInterceptorsGraph)headers[_headers.StandardHeaders.MessageInterceptorGraph.Name];
                        var message = _serialization.Serializer
                                      .BytesToMessage <MessageBody>(messagePayload, messageGraph, headers).Body;
                        var newMessage = _messageFactory.Create(message, headers);

                        return(_receivedMessageFactory.Create(newMessage,
                                                              new MessageQueueId <long>(id),
                                                              new MessageCorrelationId <Guid>(correlationId)));
                    }
                    catch (Exception error)
                    {
                        //at this point, the record has been de-queued, but it can't be processed.
                        throw new PoisonMessageException(
                                  "An error has occurred trying to re-assemble a message de-queued from the server ", error,
                                  new MessageQueueId <long>(id), new MessageCorrelationId <Guid>(correlationId), messagePayload,
                                  headerPayload);
                    }
                }
            }
        }