コード例 #1
0
        public void RemoveTask(RevaleeTask task)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            if (_EseInstance == null)
            {
                throw new InvalidOperationException("Storage provider has not been opened.");
            }

            EseConnection connection = _ConnectionPool.OpenConnection();

            try
            {
                using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.Updatable))
                {
                    using (var transaction = new Transaction(connection))
                    {
                        Api.JetSetCurrentIndex(connection, table, null);
                        Api.MakeKey(connection, table, task.CallbackId, MakeKeyGrbit.NewKey);
                        if (Api.TrySeek(connection, table, SeekGrbit.SeekEQ))
                        {
                            Api.JetDelete(connection, table);
                            transaction.Commit(CommitTransactionGrbit.None);
                        }
                    }
                }
            }
            finally
            {
                _ConnectionPool.CloseConnection(connection);
            }
        }
コード例 #2
0
        public RevaleeTask GetTask(Guid callbackId)
        {
            if (_EseInstance == null)
            {
                throw new InvalidOperationException("Storage provider has not been opened.");
            }

            EseConnection connection = _ConnectionPool.OpenConnection();

            try
            {
                using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.Updatable))
                {
                    IDictionary <string, JET_COLUMNID> columnIds = connection.GetSchema(_TableNameCallbacks);

                    Api.JetSetCurrentIndex(connection, table, null);
                    Api.MakeKey(connection, table, callbackId, MakeKeyGrbit.NewKey);
                    if (Api.TrySeek(connection, table, SeekGrbit.SeekEQ))
                    {
                        Guid?    storedCallbackId        = Api.RetrieveColumnAsGuid(connection, table, columnIds[_ColumnNameCallbackId]);
                        DateTime?createdTime             = Api.RetrieveColumnAsDateTime(connection, table, columnIds[_ColumnNameCreatedTime]);
                        DateTime?callbackTime            = Api.RetrieveColumnAsDateTime(connection, table, columnIds[_ColumnNameCallbackTime]);
                        string   callbackUrl             = Api.RetrieveColumnAsString(connection, table, columnIds[_ColumnNameCallbackUrl]);
                        int?     attemptsRemainingColumn = Api.RetrieveColumnAsInt32(connection, table, columnIds[_ColumnNameAttemptsRemaining]);
                        string   authorizationCipher     = Api.RetrieveColumnAsString(connection, table, columnIds[_ColumnNameAuthorizationCipher]);

                        Uri callbackUri = null;

                        if (callbackTime.HasValue &&
                            Uri.TryCreate(callbackUrl, UriKind.Absolute, out callbackUri) &&
                            createdTime.HasValue &&
                            storedCallbackId.HasValue &&
                            attemptsRemainingColumn.HasValue)
                        {
                            RevaleeTask revivedTask = RevaleeTask.Revive(
                                DateTime.SpecifyKind(callbackTime.Value, DateTimeKind.Utc),
                                callbackUri,
                                DateTime.SpecifyKind(createdTime.Value, DateTimeKind.Utc),
                                storedCallbackId.Value,
                                attemptsRemainingColumn.Value,
                                string.IsNullOrEmpty(authorizationCipher) ? null : authorizationCipher);

                            return(revivedTask);
                        }
                    }
                }

                return(null);
            }
            finally
            {
                _ConnectionPool.CloseConnection(connection);
            }
        }
コード例 #3
0
ファイル: StateManager.cs プロジェクト: Philo/Revalee
		public void AddTask(RevaleeTask task)
		{
			if (task == null)
			{
				throw new ArgumentNullException("task");
			}

			lock (_SyncRoot)
			{
				_PersistenceProvider.AddTask(task);
			}

			_AwaitingTaskCollection.AddOrReplace(task.CallbackId, task, task.CallbackTime);
			Supervisor.Telemetry.IncrementAwaitingTasksValue();
			ResetTaskAlarm();
		}
コード例 #4
0
        public void AddTask(RevaleeTask task)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            if (_EseInstance == null)
            {
                throw new InvalidOperationException("Storage provider has not been opened.");
            }

            EseConnection connection = _ConnectionPool.OpenConnection();

            try
            {
                using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.Updatable))
                {
                    IDictionary<string, JET_COLUMNID> columnIds = connection.GetSchema(_TableNameCallbacks);

                    using (var transaction = new Transaction(connection))
                    {
                        using (var update = new Update(connection, table, JET_prep.Insert))
                        {
                            Api.SetColumn(connection, table, columnIds[_ColumnNameCallbackId], task.CallbackId);
                            Api.SetColumn(connection, table, columnIds[_ColumnNameCreatedTime], EnforceMinimumDateTime(task.CreatedTime));
                            Api.SetColumn(connection, table, columnIds[_ColumnNameCallbackTime], EnforceMinimumDateTime(task.CallbackTime));
                            Api.SetColumn(connection, table, columnIds[_ColumnNameCallbackUrl], task.CallbackUrl.OriginalString, Encoding.Unicode);
                            Api.SetColumn(connection, table, columnIds[_ColumnNameAttemptsRemaining], task.AttemptsRemaining);

                            if (task.AuthorizationCipher != null)
                            {
                                Api.SetColumn(connection, table, columnIds[_ColumnNameAuthorizationCipher], task.AuthorizationCipher, Encoding.Unicode);
                            }

                            update.Save();
                        }

                        transaction.Commit(CommitTransactionGrbit.None);
                    }
                }
            }
            finally
            {
                _ConnectionPool.CloseConnection(connection);
            }
        }
コード例 #5
0
        public void AddTask(RevaleeTask task)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            if (_EseInstance == null)
            {
                throw new InvalidOperationException("Storage provider has not been opened.");
            }

            EseConnection connection = _ConnectionPool.OpenConnection();

            try
            {
                using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.Updatable))
                {
                    IDictionary <string, JET_COLUMNID> columnIds = connection.GetSchema(_TableNameCallbacks);

                    using (var transaction = new Transaction(connection))
                    {
                        using (var update = new Update(connection, table, JET_prep.Insert))
                        {
                            Api.SetColumn(connection, table, columnIds[_ColumnNameCallbackId], task.CallbackId);
                            Api.SetColumn(connection, table, columnIds[_ColumnNameCreatedTime], EnforceMinimumDateTime(task.CreatedTime));
                            Api.SetColumn(connection, table, columnIds[_ColumnNameCallbackTime], EnforceMinimumDateTime(task.CallbackTime));
                            Api.SetColumn(connection, table, columnIds[_ColumnNameCallbackUrl], task.CallbackUrl.OriginalString, Encoding.Unicode);
                            Api.SetColumn(connection, table, columnIds[_ColumnNameAttemptsRemaining], task.AttemptsRemaining);

                            if (task.AuthorizationCipher != null)
                            {
                                Api.SetColumn(connection, table, columnIds[_ColumnNameAuthorizationCipher], task.AuthorizationCipher, Encoding.Unicode);
                            }

                            update.Save();
                        }

                        transaction.Commit(CommitTransactionGrbit.None);
                    }
                }
            }
            finally
            {
                _ConnectionPool.CloseConnection(connection);
            }
        }
コード例 #6
0
		private static void FinalizeAcceptedResponse(HttpListenerRequest request, HttpListenerResponse response, RevaleeTask task)
		{
			string remoteAddress = request.RemoteEndPoint.Address.ToString();

			try
			{
				response.StatusCode = 200;
				response.StatusDescription = "OK";
				byte[] confirmation_number = Encoding.UTF8.GetBytes(task.CallbackId.ToString());
				response.ContentLength64 = confirmation_number.LongLength;
				response.OutputStream.Write(confirmation_number, 0, confirmation_number.Length);
			}
			finally
			{
				response.Close();
			}

			Supervisor.Telemetry.RecordAcceptedRequest();
			Supervisor.LogEvent(string.Format("Request accepted for {0} @ {1:d} {1:t} from {2}. [{3}]", task.CallbackUrl.OriginalString, task.CallbackTime, remoteAddress, task.CallbackId), TraceEventType.Verbose);
		}
コード例 #7
0
ファイル: StateManager.cs プロジェクト: Philo/Revalee
		public void CancelTask(RevaleeTask task)
		{
			if (task == null)
			{
				throw new ArgumentNullException("task");
			}

			RevaleeTask awaitingTask;

			if (_AwaitingTaskCollection.TryGetValue(task.CallbackId, out awaitingTask))
			{
				if (awaitingTask.CallbackUrl.ToString().StartsWith(task.CallbackUrl.ToString(), StringComparison.OrdinalIgnoreCase))
				{
					RevaleeTask removedTask;
					bool wasTaskRemoved = _AwaitingTaskCollection.TryRemove(awaitingTask.CallbackId, out removedTask);

					lock (_SyncRoot)
					{
						_PersistenceProvider.RemoveTask(awaitingTask);
					}

					if (wasTaskRemoved)
					{
						Supervisor.Telemetry.DecrementAwaitingTasksValue();
					}
				}
			}
			else
			{
				RevaleeTask storedTask = RetrieveTask(task.CallbackId);

				if (storedTask != null)
				{
					if (storedTask.CallbackUrl.ToString().StartsWith(task.CallbackUrl.ToString(), StringComparison.OrdinalIgnoreCase))
					{
						lock (_SyncRoot)
						{
							_PersistenceProvider.RemoveTask(storedTask);
						}
					}
				}
			}
		}
コード例 #8
0
		public void RemoveTask(RevaleeTask Task)
		{
			return;
		}
コード例 #9
0
ファイル: WorkManager.cs プロジェクト: Philo/Revalee
		private static string FormatFormPayload(RevaleeTask task)
		{
			var payload = new StringBuilder();
			payload.Append("CallbackId=");
			payload.Append(task.CallbackId.ToString("D"));
			payload.Append("&CallbackTime=");
			payload.Append(task.CallbackTime.ToString(@"yyyy-MM-dd\THH:mm:ss.fff\Z", CultureInfo.InvariantCulture));
			payload.Append("&CurrentServiceTime=");
			payload.Append(DateTime.UtcNow.ToString(@"yyyy-MM-dd\THH:mm:ss.fff\Z", CultureInfo.InvariantCulture));
			return payload.ToString();
		}
コード例 #10
0
ファイル: WorkManager.cs プロジェクト: Philo/Revalee
		private static void CompleteRetryableTask(RevaleeTask task, Exception exception)
		{
			if (task.AttemptsRemaining > 0)
			{
				RetryTask(task);
			}
			else
			{
				// Out of attempts
				CompleteFailedTask(task, exception);
			}
		}
コード例 #11
0
ファイル: WorkManager.cs プロジェクト: Philo/Revalee
		private static void CompleteFailedTask(RevaleeTask task, Exception exception)
		{
			Supervisor.State.CompleteTask(task);
			Supervisor.LogException(exception, TraceEventType.Error, task.CallbackUrl.OriginalString);
			Supervisor.Telemetry.RecordWaitTime(CalculateWaitTime(DateTime.UtcNow, task));
			Supervisor.Telemetry.RecordFailedCallback();
		}
コード例 #12
0
ファイル: WorkManager.cs プロジェクト: Philo/Revalee
		private static void CompleteSuccessfulTask(RevaleeTask task)
		{
			Supervisor.State.CompleteTask(task);
			Supervisor.LogEvent(string.Format("Successful callback to {0}. [{1}]", task.CallbackUrl.OriginalString, task.CallbackId), TraceEventType.Verbose);
			Supervisor.Telemetry.RecordWaitTime(CalculateWaitTime(DateTime.UtcNow, task));
			Supervisor.Telemetry.RecordSuccessfulCallback();
			RetryHeuristics.OnSuccess(task.CallbackUrl);
		}
コード例 #13
0
ファイル: WorkManager.cs プロジェクト: Philo/Revalee
		private void ProcessWebResponse(RevaleeTask task, HttpWebResponse response)
		{
			switch (DetermineResult(response.StatusCode))
			{
				case CallbackResult.Success:
					CompleteSuccessfulTask(task);
					break;

				case CallbackResult.NonretryableError:
					CompleteFailedTask(task, response.StatusCode);
					break;

				default:
					CompleteRetryableTask(task, response.StatusCode);
					break;
			}
		}
コード例 #14
0
		public void Process(HttpListenerRequest request, HttpListenerResponse response)
		{
			try
			{
				if (request.HttpMethod != "PUT")
				{
					FinalizeRejectedResponse(request, response, 405, "Method Not Supported", null);
					return;
				}

				if (request.QueryString.Count < 2)
				{
					FinalizeRejectedResponse(request, response, 400, "Bad Request", null);
					return;
				}

				Uri url = RetrieveUrlParameter(request);
				if (url == null)
				{
					FinalizeRejectedResponse(request, response, 400, "Bad Request", null);
					return;
				}

				DateTime? time = RetrieveTimeParameter(request);
				if (!time.HasValue)
				{
					FinalizeRejectedResponse(request, response, 400, "Bad Request", url);
					return;
				}

				if (UrlContainsDangerousMarkup(url))
				{
					FinalizeRejectedResponse(request, response, 400, "Bad Request", url);
					return;
				}

				RevaleeUrlAuthorization authorization = Supervisor.Configuration.AuthorizedTargets.Match(url);
				if (authorization == null)
				{
					// Keep all authorization errors homogeneous from the client perspective
					RevaleeUrlAuthorization.ObfuscateExecutionTime();
					FinalizeRejectedResponse(request, response, 401, "Unauthorized", url);
					return;
				}

				if (!authorization.IsAuthorizedRequestSource(request.RemoteEndPoint.Address))
				{
					// Keep all authorization errors homogeneous from the client perspective
					RevaleeUrlAuthorization.ObfuscateExecutionTime();
					FinalizeRejectedResponse(request, response, 401, "Unauthorized", url);
					return;
				}

				if (Supervisor.Work.IsOverloaded)
				{
					FinalizeRejectedResponse(request, response, 503, "Service Unavailable", url);
					return;
				}

				string authorizationCipher = RetrieveAuthorizationHeader(request);

				RevaleeTask newTask = new RevaleeTask(time.Value, url, authorization.RetryCount, authorizationCipher);
				Supervisor.State.AddTask(newTask);

				FinalizeAcceptedResponse(request, response, newTask);
				return;
			}
			catch (HttpListenerException hlex)
			{
				Supervisor.LogException(hlex, TraceEventType.Error, request.RawUrl);
				FinalizeRejectedResponse(request, response, 500, "Error Occurred", null);
				return;
			}
		}
コード例 #15
0
ファイル: WorkManager.cs プロジェクト: rodrycode/Revalee
 private static void CompleteFailedTask(RevaleeTask task, string message)
 {
     Supervisor.State.CompleteTask(task);
     Supervisor.LogEvent(message, TraceEventType.Error);
     Supervisor.Telemetry.RecordWaitTime(CalculateWaitTime(DateTime.UtcNow, task));
     Supervisor.Telemetry.RecordFailedCallback();
 }
コード例 #16
0
ファイル: WorkManager.cs プロジェクト: rodrycode/Revalee
 private static string FormatWebExceptionMessage(RevaleeTask task, WebException webException)
 {
     return string.Format("Unsuccessful callback to {0} with status '{1}'. [{2}]",
         task.CallbackUrl.OriginalString, webException.Status.ToString(), task.CallbackId);
 }
コード例 #17
0
ファイル: WorkManager.cs プロジェクト: rodrycode/Revalee
 private static string FormatHttpErrorMessage(RevaleeTask task, HttpStatusCode statusCode)
 {
     return string.Format("Unsuccessful callback to {0} due to HTTP status code {1}. [{2}]",
         task.CallbackUrl.OriginalString, (int)statusCode, task.CallbackId);
 }
コード例 #18
0
ファイル: WorkManager.cs プロジェクト: rodrycode/Revalee
 private static string FormatGenericExceptionMessage(RevaleeTask task, Exception exception)
 {
     return string.Format("{0} [{1}]", exception.Message, task.CallbackUrl.OriginalString);
 }
コード例 #19
0
ファイル: WorkManager.cs プロジェクト: rodrycode/Revalee
 private static void CompleteRetryableTask(RevaleeTask task, string message)
 {
     if (task.AttemptsRemaining > 0)
     {
         Supervisor.LogEvent(message, TraceEventType.Warning);
         RetryTask(task);
     }
     else
     {
         // Out of attempts
         CompleteFailedTask(task, message);
     }
 }
コード例 #20
0
        public void RemoveTask(RevaleeTask task)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            if (_EseInstance == null)
            {
                throw new InvalidOperationException("Storage provider has not been opened.");
            }

            EseConnection connection = _ConnectionPool.OpenConnection();

            try
            {
                using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.Updatable))
                {
                    using (var transaction = new Transaction(connection))
                    {
                        Api.JetSetCurrentIndex(connection, table, null);
                        Api.MakeKey(connection, table, task.CallbackId, MakeKeyGrbit.NewKey);
                        if (Api.TrySeek(connection, table, SeekGrbit.SeekEQ))
                        {
                            Api.JetDelete(connection, table);
                            transaction.Commit(CommitTransactionGrbit.None);
                        }
                    }
                }
            }
            finally
            {
                _ConnectionPool.CloseConnection(connection);
            }
        }
コード例 #21
0
        public IEnumerable <RevaleeTask> ListAllTasks()
        {
            if (_EseInstance == null)
            {
                throw new InvalidOperationException("Storage provider has not been opened.");
            }

            EseConnection connection = this._ConnectionPool.OpenConnection();

            try
            {
                using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.DenyWrite | OpenTableGrbit.Preread | OpenTableGrbit.ReadOnly | OpenTableGrbit.Sequential))
                {
                    IDictionary <string, JET_COLUMNID> columnIds = connection.GetSchema(_TableNameCallbacks);

                    if (Api.TryMoveFirst(connection, table))
                    {
                        JET_SESID    jetSession                   = connection;
                        JET_TABLEID  jetTable                     = table;
                        JET_COLUMNID jetColumnCallbackId          = columnIds[_ColumnNameCallbackId];
                        JET_COLUMNID jetColumnCreatedTime         = columnIds[_ColumnNameCreatedTime];
                        JET_COLUMNID jetColumnCallbackTime        = columnIds[_ColumnNameCallbackTime];
                        JET_COLUMNID jetColumnCallbackUrl         = columnIds[_ColumnNameCallbackUrl];
                        JET_COLUMNID jetColumnAttemptsRemaining   = columnIds[_ColumnNameAttemptsRemaining];
                        JET_COLUMNID jetColumnAuthorizationCipher = columnIds[_ColumnNameAuthorizationCipher];

                        do
                        {
                            Guid?    callbackId              = Api.RetrieveColumnAsGuid(jetSession, jetTable, jetColumnCallbackId);
                            DateTime?createdTime             = Api.RetrieveColumnAsDateTime(jetSession, jetTable, jetColumnCreatedTime);
                            DateTime?callbackTime            = Api.RetrieveColumnAsDateTime(jetSession, jetTable, jetColumnCallbackTime);
                            string   callbackUrl             = Api.RetrieveColumnAsString(jetSession, jetTable, jetColumnCallbackUrl);
                            int?     attemptsRemainingColumn = Api.RetrieveColumnAsInt32(jetSession, jetTable, jetColumnAttemptsRemaining);
                            string   authorizationCipher     = Api.RetrieveColumnAsString(jetSession, jetTable, jetColumnAuthorizationCipher);

                            Uri callbackUri = null;

                            if (callbackTime.HasValue &&
                                Uri.TryCreate(callbackUrl, UriKind.Absolute, out callbackUri) &&
                                createdTime.HasValue &&
                                callbackId.HasValue &&
                                attemptsRemainingColumn.HasValue)
                            {
                                RevaleeTask revivedTask = RevaleeTask.Revive(
                                    DateTime.SpecifyKind(callbackTime.Value, DateTimeKind.Utc),
                                    callbackUri,
                                    DateTime.SpecifyKind(createdTime.Value, DateTimeKind.Utc),
                                    callbackId.Value,
                                    attemptsRemainingColumn.Value,
                                    string.IsNullOrEmpty(authorizationCipher) ? null : authorizationCipher);

                                yield return(revivedTask);
                            }
                        } while (Api.TryMoveNext(jetSession, jetTable));
                    }
                }
            }
            finally
            {
                _ConnectionPool.CloseConnection(connection);
            }

            yield break;
        }
コード例 #22
0
ファイル: WorkManager.cs プロジェクト: Philo/Revalee
		private static HttpWebRequest PrepareWebRequest(RevaleeTask task)
		{
			HttpWebRequest request = (HttpWebRequest)WebRequest.Create(FormatCallbackRequestUrl(task.CallbackUrl));
			request.AllowAutoRedirect = true;
			request.MaximumAutomaticRedirections = 10;
			request.KeepAlive = false;
			request.Method = "POST";
			request.Pipelined = false;
			request.Timeout = 30000;
			request.UserAgent = "Revalee";
			request.ContentType = "application/x-www-form-urlencoded";

			if (!string.IsNullOrEmpty(task.AuthorizationCipher))
			{
				string responseCipher = BuildResponseAuthorizationCipher(task.AuthorizationCipher, task.CallbackId);

				if (responseCipher != null)
				{
					request.Headers.Add("Revalee-Auth", responseCipher);
				}
			}

			string postedData = FormatFormPayload(task);
			request.ContentLength = postedData.Length;
			using (Stream stream = request.GetRequestStream())
			{
				stream.Write(Encoding.UTF8.GetBytes(postedData), 0, postedData.Length);
			}

			return request;
		}
コード例 #23
0
        public IEnumerable <RevaleeTask> ListTasksDueBetween(DateTime startTime, DateTime endTime)
        {
            if (_EseInstance == null)
            {
                throw new InvalidOperationException("Storage provider has not been opened.");
            }

            DateTime rangeStartTime = EnforceMinimumDateTime(NormalizeDateTime(startTime));
            DateTime rangeEndTime   = EnforceMinimumDateTime(NormalizeDateTime(endTime));

            // Inclusive Upper Limit does not work properly for the CLR DateTime type.
            // Add the smallest amount of time that the Esent engine will detect to include the ending range inclusively.
            rangeEndTime = rangeEndTime.AddMilliseconds(1.0);

            EseConnection connection = this._ConnectionPool.OpenConnection();

            try
            {
                using (Table table = connection.GetTable(_TableNameCallbacks, OpenTableGrbit.DenyWrite | OpenTableGrbit.Preread | OpenTableGrbit.ReadOnly | OpenTableGrbit.Sequential))
                {
                    IDictionary <string, JET_COLUMNID> columnIds = connection.GetSchema(_TableNameCallbacks);
                    Api.JetSetCurrentIndex(connection, table, "due");
                    Api.MakeKey(connection, table, rangeStartTime, MakeKeyGrbit.NewKey);

                    if (Api.TrySeek(connection, table, SeekGrbit.SeekGE))
                    {
                        Api.MakeKey(connection, table, rangeEndTime, MakeKeyGrbit.NewKey);
                        if (Api.TrySetIndexRange(connection, table, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit))
                        {
                            JET_SESID    jetSession                   = connection;
                            JET_TABLEID  jetTable                     = table;
                            JET_COLUMNID jetColumnCallbackId          = columnIds[_ColumnNameCallbackId];
                            JET_COLUMNID jetColumnCreatedTime         = columnIds[_ColumnNameCreatedTime];
                            JET_COLUMNID jetColumnCallbackTime        = columnIds[_ColumnNameCallbackTime];
                            JET_COLUMNID jetColumnCallbackUrl         = columnIds[_ColumnNameCallbackUrl];
                            JET_COLUMNID jetColumnAttemptsRemaining   = columnIds[_ColumnNameAttemptsRemaining];
                            JET_COLUMNID jetColumnAuthorizationCipher = columnIds[_ColumnNameAuthorizationCipher];

                            do
                            {
                                Guid?    callbackId              = Api.RetrieveColumnAsGuid(jetSession, jetTable, jetColumnCallbackId);
                                DateTime?createdTime             = Api.RetrieveColumnAsDateTime(jetSession, jetTable, jetColumnCreatedTime);
                                DateTime?callbackTime            = Api.RetrieveColumnAsDateTime(jetSession, jetTable, jetColumnCallbackTime);
                                string   callbackUrl             = Api.RetrieveColumnAsString(jetSession, jetTable, jetColumnCallbackUrl);
                                int?     attemptsRemainingColumn = Api.RetrieveColumnAsInt32(jetSession, jetTable, jetColumnAttemptsRemaining);
                                string   authorizationCipher     = Api.RetrieveColumnAsString(jetSession, jetTable, jetColumnAuthorizationCipher);

                                Uri callbackUri = null;

                                if (callbackTime.HasValue &&
                                    Uri.TryCreate(callbackUrl, UriKind.Absolute, out callbackUri) &&
                                    createdTime.HasValue &&
                                    callbackId.HasValue &&
                                    attemptsRemainingColumn.HasValue)
                                {
                                    RevaleeTask revivedTask = RevaleeTask.Revive(
                                        DateTime.SpecifyKind(callbackTime.Value, DateTimeKind.Utc),
                                        callbackUri,
                                        DateTime.SpecifyKind(createdTime.Value, DateTimeKind.Utc),
                                        callbackId.Value,
                                        attemptsRemainingColumn.Value,
                                        string.IsNullOrEmpty(authorizationCipher) ? null : authorizationCipher);

                                    yield return(revivedTask);
                                }
                            } while (Api.TryMoveNext(jetSession, jetTable));
                        }
                    }
                }
            }
            finally
            {
                _ConnectionPool.CloseConnection(connection);
            }

            yield break;
        }
コード例 #24
0
ファイル: WorkManager.cs プロジェクト: Philo/Revalee
		private void ProcessWebException(RevaleeTask task, WebException wex)
		{
			HttpWebResponse failedResponse = (HttpWebResponse)wex.Response;
			if (failedResponse != null)
			{
				switch (DetermineResult(failedResponse.StatusCode))
				{
					case CallbackResult.NonretryableError:
						CompleteFailedTask(task, failedResponse.StatusCode);
						break;

					default:
						CompleteRetryableTask(task, failedResponse.StatusCode);
						break;
				}
			}
			else
			{
				CompleteRetryableTask(task, wex);
			}
		}
コード例 #25
0
ファイル: StateManager.cs プロジェクト: Philo/Revalee
		public void CompleteTask(RevaleeTask task)
		{
			if (task == null)
			{
				throw new ArgumentNullException("task");
			}

			lock (_SyncRoot)
			{
				_PersistenceProvider.RemoveTask(task);
				Supervisor.Telemetry.DecrementAwaitingTasksValue();
			}
		}
コード例 #26
0
ファイル: WorkManager.cs プロジェクト: Philo/Revalee
		private static void CompleteFailedTask(RevaleeTask task, HttpStatusCode statusCode)
		{
			Supervisor.State.CompleteTask(task);
			Supervisor.LogEvent(string.Format("Unsuccessful callback to {0} due to HTTP status code {1}. [{2}]",
				task.CallbackUrl.OriginalString, (int)statusCode, task.CallbackId), TraceEventType.Error);
			Supervisor.Telemetry.RecordWaitTime(CalculateWaitTime(DateTime.UtcNow, task));
			Supervisor.Telemetry.RecordFailedCallback();
		}
コード例 #27
0
ファイル: StateManager.cs プロジェクト: Philo/Revalee
		public void UpdateTask(RevaleeTask task)
		{
			if (task == null)
			{
				throw new ArgumentNullException("task");
			}

			lock (_SyncRoot)
			{
				_PersistenceProvider.RemoveTask(task);
				_PersistenceProvider.AddTask(task);
			}
		}
コード例 #28
0
ファイル: WorkManager.cs プロジェクト: Philo/Revalee
		private static void CompleteRetryableTask(RevaleeTask task, HttpStatusCode statusCode)
		{
			if (task.AttemptsRemaining > 0)
			{
				RetryTask(task);
			}
			else
			{
				// Out of attempts
				CompleteFailedTask(task, statusCode);
			}
		}
コード例 #29
0
ファイル: StateManager.cs プロジェクト: Philo/Revalee
		public void ReenlistTask(RevaleeTask task)
		{
			if (task == null)
			{
				throw new ArgumentNullException("task");
			}

			_AwaitingTaskCollection.AddOrReplace(task.CallbackId, task, task.CallbackTime);
			ResetTaskAlarm();
		}
コード例 #30
0
ファイル: WorkManager.cs プロジェクト: Philo/Revalee
		private static void RetryTask(RevaleeTask task)
		{
			// Update the persisted attempt counts
			Supervisor.State.UpdateTask(task);

			// Reenlist task to be retried later
			TimeSpan retryDelay = RetryHeuristics.OnRetryableFailure(task.CallbackUrl);
			DateTime delayedCallbackTime = DateTime.UtcNow.Add(retryDelay);
			Supervisor.State.ReenlistTask(task, delayedCallbackTime);
			Supervisor.LogEvent(string.Format("Retrying callback to {0} after waiting {1}. [{2}]", task.CallbackUrl.OriginalString, retryDelay, task.CallbackId), TraceEventType.Information);
		}
コード例 #31
0
ファイル: StateManager.cs プロジェクト: Philo/Revalee
		public void ReenlistTask(RevaleeTask task, DateTime due)
		{
			if (task == null)
			{
				throw new ArgumentNullException("task");
			}

			if (due.Kind != DateTimeKind.Utc)
			{
				throw new ArgumentException("DateTime argument not provided in UTC.", "due");
			}

			_AwaitingTaskCollection.AddOrReplace(task.CallbackId, task, due);
			ResetTaskAlarm();
		}
コード例 #32
0
ファイル: WorkManager.cs プロジェクト: Philo/Revalee
		private static TimeSpan CalculateWaitTime(DateTime time, RevaleeTask task)
		{
			if (task.CallbackTime > task.CreatedTime)
			{
				if (task.CallbackTime < time)
				{
					return time.Subtract(task.CallbackTime);
				}
				else
				{
					return TimeSpan.Zero;
				}
			}
			else
			{
				if (task.CreatedTime < time)
				{
					return time.Subtract(task.CreatedTime);
				}
				else
				{
					return TimeSpan.Zero;
				}
			}
		}
コード例 #33
0
		public void AddTask(RevaleeTask Task)
		{
			return;
		}