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