Просмотр исходного кода

Add TaskItem, ProcessQueue (not complete)

Dalibor Votruba 2 лет назад
Родитель
Сommit
a3246eb9ee

+ 29 - 0
Workbench/Processor/Dependencies/Data/TypedArgument.cs

@@ -0,0 +1,29 @@
+using System;
+
+namespace Quadarax.Foundation.Core.Object;
+
+public class TypedArgument
+{
+    public string Name {get; private set;}
+    public string Value {get; private set;}  //TODO: must be nullable
+    public Type ValueType {get; private set;}
+       
+    public bool IsOutput {get; private set;}
+       
+    public TypedArgument(string name, string valueAsString, Type valueType, bool isOutput = false)
+    {
+        Name = name ?? throw new ArgumentNullException(nameof(name));
+        ValueType = valueType ?? throw new ArgumentNullException(nameof(valueType));
+        Value = valueAsString;
+        IsOutput = isOutput;
+    }
+    public TypedArgument(string name, Type valueType, bool isOutput = false) : this(name, string.Empty, valueType, isOutput)
+    {
+         
+    }
+    public TypedArgument(string name, object valueTyped, bool isOutput = false) : this(name, valueTyped?.ToString(), valueTyped?.GetType(), isOutput)
+    {
+         
+    }  
+}
+   

+ 41 - 0
Workbench/Processor/Dependencies/Logging/ConsoleLog.cs

@@ -0,0 +1,41 @@
+namespace Quadarax.Foundation.Core.Logging
+{
+    public class ConsoleLog : ILog
+    {
+        private string _typeName;
+
+        public ConsoleLog(Type owningType)
+        {
+            _typeName = owningType.Name;
+        }
+
+        public ConsoleLog(string owningTypeName)
+        {
+            _typeName = owningTypeName;
+        }
+
+        public void Log(LogSeverityEnum severity, int code, string message)
+        {
+			Log(severity, $"Code:{code}, {message}");            
+        }
+
+        public void Log(LogSeverityEnum severity, string message)
+        {
+            var now = DateTime.Now;
+            var thNum = Thread.CurrentThread.ManagedThreadId;
+
+            var final = $"[{severity}:{now.ToLongTimeString()}:{thNum}]#{_typeName}: {message}";
+            Console.WriteLine(final);
+        }
+
+        public void Log(LogSeverityEnum severity, string message, Exception exception)
+        {
+            Log(severity, $"{message}\n{exception}");
+        }
+
+        public void Log(LogSeverityEnum severity, int code, string message, Exception exception)
+        {
+            Log(severity, string.Format("{2} - {0}\n{1}", message,exception, code));
+        }
+    }
+}

+ 17 - 0
Workbench/Processor/Dependencies/Logging/ConsoleLogger.cs

@@ -0,0 +1,17 @@
+using ProcessingQueue.Externals;
+
+namespace Quadarax.Foundation.Core.Logging
+{
+    public class ConsoleLogger : ILogger
+    {
+        public ILog GetLogger(string loggerName)
+        {
+            return new ConsoleLog(loggerName);
+        }
+
+        public ILog GetLogger(Type loggerForType)
+        {
+            return new ConsoleLog(loggerForType);
+        }
+    }
+}

+ 13 - 0
Workbench/Processor/Dependencies/Value/Extensions/ArrayExt.cs

@@ -0,0 +1,13 @@
+namespace Quadarax.Foundation.Core.Value.Extensions
+{
+    public static class ArrayExt
+    {
+        public static int IndexOf<TValue>(this TValue[] owner,TValue findValue, int startIndex, int endIndex)
+        {
+            for(int i = startIndex; i < endIndex; i++)
+                if (Equals(owner[i], findValue))
+                    return i;
+            return -1;
+        }
+    }
+}

+ 25 - 0
Workbench/Processor/Dependencies/Value/Extensions/DateTimeExt.cs

@@ -0,0 +1,25 @@
+using System;
+
+namespace Quadarax.Foundation.Core.Value.Extensions
+{
+    public static class DateTimeExt
+    {
+        public static string ToFileShortDateString(this DateTime owner)
+        {
+            return owner.ToString("yyyyMMdd");
+        }
+
+        public static string ToFileShortTimeString(this DateTime owner)
+        {
+            return owner.ToString("HHmmss");
+        }
+        public static string ToFileShortDateTimeString(this DateTime owner)
+        {
+            return owner.ToFileShortDateString() + "-" + owner.ToFileShortTimeString();
+        }
+        public static string ToFileUtcString(this DateTime owner)
+        {
+            return owner.ToUniversalTime().ToString("yyyy-MM-ddT-HH-mm-ss-fff");
+        }
+    }
+}

+ 49 - 0
Workbench/Processor/Dependencies/Value/Extensions/EnumerableExt.cs

@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Quadarax.Foundation.Core.Value.Extensions
+{
+    public static class EnumerableExt
+    {
+        private static Random _rand = new Random();
+        private const string CS_MESSAGE_MUST_HAVE_ONE = "Collection must have at least one element.";
+        private const string CS_MESSAGE_MUST_POSITIVE = "Must be positive number.";
+        private const string CS_MESSAGE_MUST_SMALLER = "fromIndex must be smaller or equal to toIndex.";
+
+
+        public static TElement GetRandom<TElement>(this IEnumerable<TElement> owner)
+        {
+            if (owner == null)
+                throw new ArgumentNullException(nameof(owner));
+
+            if (!owner.Any())
+                throw new ArgumentOutOfRangeException(nameof(owner), CS_MESSAGE_MUST_HAVE_ONE);
+
+            return GetRandom(owner, 0, owner.Count());
+        }
+
+        public static TElement GetRandom<TElement>(this IEnumerable<TElement> owner, int fromIndex, int toIndex = -1)
+        {
+            if (owner == null)
+                throw new ArgumentNullException(nameof(owner));
+
+            if (!owner.Any())
+                throw new ArgumentOutOfRangeException(nameof(owner), CS_MESSAGE_MUST_HAVE_ONE);
+
+            if (toIndex == -1)
+                toIndex = owner.Count() - 1;
+            if (fromIndex<0)
+                throw new ArgumentOutOfRangeException(nameof(fromIndex), CS_MESSAGE_MUST_POSITIVE);
+            if (toIndex<0)
+                throw new ArgumentOutOfRangeException(nameof(fromIndex), CS_MESSAGE_MUST_POSITIVE);
+            if (fromIndex>toIndex)
+                throw new ArgumentOutOfRangeException(nameof(fromIndex), CS_MESSAGE_MUST_SMALLER);
+
+            var index = _rand.Next(fromIndex, toIndex);
+            return owner.Skip(index).Take(1).First();
+
+
+        }
+    }
+}

+ 28 - 0
Workbench/Processor/Dependencies/Value/Extensions/ListExt.cs

@@ -0,0 +1,28 @@
+namespace Quadarax.Foundation.Core.Value.Extensions
+{
+    public static class ListExt
+    {
+        public static void Setup<TItem>(this IList<TItem> owner, IEnumerable<TItem> newItems)
+        {
+            if (owner == null)
+                throw new ArgumentNullException(nameof(owner));
+            if (newItems == null)
+                throw new ArgumentNullException(nameof(newItems));
+
+            owner.Clear();
+            owner.AddRange(newItems);
+
+        }
+
+        public static void AddRange<TItem>(this IList<TItem> owner, IEnumerable<TItem> items)
+        {
+            if (owner == null)
+                throw new ArgumentNullException(nameof(owner));
+            if (items == null)
+                throw new ArgumentNullException(nameof(items));
+
+            foreach (var item in items)
+                owner.Add(item);
+        }
+    }
+}

+ 17 - 0
Workbench/Processor/Dependencies/Value/Extensions/LongExt.cs

@@ -0,0 +1,17 @@
+namespace Quadarax.Foundation.Core.Value.Extensions
+{
+    public static class LongExt
+    {
+        public static string ToReadableLengthString(this long owner)
+        {
+            string[] sizes = { "B", "KB", "MB", "GB", "TB" };
+            var order = 0;
+            while (owner >= 1024 && order < sizes.Length - 1) {
+                order++;
+                owner /= 1024;
+            }
+
+            return $"{owner:0.##} {sizes[order]}";
+        }
+    }
+}

+ 147 - 0
Workbench/Processor/Dependencies/Value/Extensions/StringExt.cs

@@ -0,0 +1,147 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace Quadarax.Foundation.Core.Value.Extensions
+{
+    public static class StringExt
+    {
+        public static string Align(this string value, int size)
+        {
+            if (string.IsNullOrEmpty(value)) return new string(' ', size);
+            if (value.Length < size)
+                return value + new string(' ',  size - value.Length);
+            return Truncate(value, size);
+        }
+        public static string Truncate(this string value, int maxLength)
+        {
+            if (string.IsNullOrEmpty(value)) return value;
+            return value.Length <= maxLength ? value : value.Substring(0, maxLength); 
+        }
+        
+        public static int SeparateValueCount(this string value, string separator)
+        {
+            var nSepLen = separator.Length;
+            var nStrLen = value.Length;
+            if (nStrLen == 0 || nSepLen == 0)
+                return nSepLen == 0 && nStrLen > 0 ? 1 : 0;
+            var nCnt = 0;
+            var nPos = value.IndexOf(separator, StringComparison.Ordinal);
+            while (nPos >= 0)
+            {
+                nCnt++;
+                nPos = value.IndexOf(separator, nPos + nSepLen, StringComparison.Ordinal);
+            }
+            return nCnt + 1;
+
+        }
+        public static string SeparateValue(this string value, string separator, int zeroBasedIndex)
+        {
+            var nSepLen = separator.Length;
+            var nStrLen = value.Length;
+            if (nStrLen == 0 || nSepLen == 0 || nSepLen > nStrLen)
+                throw new IndexOutOfRangeException("SeparateValue method has index out of range.");
+            var nLastPos = 0;
+            var nPos = value.IndexOf(separator, StringComparison.Ordinal);
+            while (nPos >= 0)
+            {
+                if (zeroBasedIndex == 0)
+                    break;
+                nLastPos = nPos + nSepLen;
+                nPos = value.IndexOf(separator, nPos + nSepLen, StringComparison.Ordinal);
+                zeroBasedIndex--;
+            }
+            if (zeroBasedIndex > 0)
+                throw new IndexOutOfRangeException("SeparateValue method has index out of range.");
+            return value.Substring(nLastPos, nPos == -1 ? nStrLen - nLastPos : nPos - nLastPos);
+        }
+        public static string SeparateValueLast(this string value, string separator)
+        {
+            var nSepLen = separator.Length;
+            var nStrLen = value.Length;
+            if (nStrLen == 0 || nSepLen == 0 || nSepLen > nStrLen)
+                throw new IndexOutOfRangeException("SeparateValue method has index out of range.");
+            return value.SeparateValue(separator, value.SeparateValueCount(separator) - 1);
+        }
+        public static string RemoveLast(this string value)
+        {
+            return value.Length == 0 ? string.Empty : value.Substring(0, value.Length - 1);
+        }
+        public static string RemoveFirst(this string value)
+        {
+            return value.Length == 0 ? string.Empty : value.Substring(1, value.Length - 1);
+        }
+
+        public static int MaxLineChars(this string value)
+        {
+            var aParts = value.Split("/n");
+            return aParts.Length > 0 ? aParts.Max(x => x.Length) : value.Length;
+        }
+
+        public static string[] Split(this string value, string separator)
+        {
+            return value.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries);
+        }
+
+        public static Tuple<string, string>[] Extract(this string value, params string[] hashes) //hashtype, tashname
+        {
+
+            var oResult = new List<Tuple<string, string>>();
+            if (hashes.Length == 0)
+                return new Tuple<string, string>[0];
+            var nLenIndex = value.Length + 1;
+            foreach (var sHash in hashes)
+            {
+                var bBeginBlock = true;
+                var nPos = value.IndexOf(sHash, StringComparison.InvariantCulture);
+                var nLenHash = sHash.Length;
+                if (nPos < 0)
+                    continue;
+                while (nPos >= 0)
+                {
+                    if (nPos + nLenHash > nLenIndex)
+                        break;
+                    var nEndPos = value.IndexOf(sHash, nPos + nLenHash, StringComparison.InvariantCulture);
+                    if (nEndPos < 0)
+                        break;
+                    if (bBeginBlock)
+                    {
+                        var oEntry = new Tuple<string, string>(sHash, value.Substring(nPos + nLenHash, nEndPos - nPos - nLenHash));
+                        if (!oResult.Contains(oEntry))
+                            oResult.Add(oEntry);
+                    }
+                    nPos = nEndPos;
+                    bBeginBlock = !bBeginBlock;
+                }
+            }
+            return oResult.ToArray();
+        }
+
+        public static string EnsurePathBackslash(this string value)
+        {
+            if (string.IsNullOrEmpty(value))
+                return value;
+            value = value.Trim();
+            if (value.EndsWith(Path.DirectorySeparatorChar))
+                return value;
+            return value + Path.DirectorySeparatorChar;
+        }
+        public static string EnsurePathNonBackslash(this string value)
+        {
+            if (string.IsNullOrEmpty(value))
+                return value;
+            value = value.Trim();
+            if (!value.EndsWith(Path.DirectorySeparatorChar))
+                return value;
+            return value.RemoveLast();
+        }
+
+        public static string RemoveWhitespace(this string input)
+        {
+            return new string(input.ToCharArray()
+                .Where(c => !Char.IsWhiteSpace(c))
+                .ToArray());
+        }
+    }
+}

+ 41 - 0
Workbench/Processor/Dependencies/Value/Extensions/TimeSpanExt.cs

@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Quadarax.Foundation.Core.Value.Formatters;
+
+namespace Quadarax.Foundation.Core.Value.Extensions
+{
+    public static class TimeSpanExt
+    {
+        public static string ToReadableString(this TimeSpan owner)
+        {
+            if (owner == null)
+                throw new ArgumentNullException(nameof(owner));
+
+            // formats and its cutoffs based on TotalSeconds
+            var cutoff = new SortedList<long, string> { 
+                {59, "{3:S}" }, 
+                {60, "{2:M}" },
+                {60*60-1, "{2:M}, {3:S}"},
+                {60*60, "{1:H}"},
+                {24*60*60-1, "{1:H}, {2:M}"},
+                {24*60*60, "{0:D}"},
+                {Int64.MaxValue , "{0:D}, {1:H}"}
+            };
+
+            // find nearest best match
+            var find = cutoff.Keys.ToList()
+                .BinarySearch((long)owner.TotalSeconds);
+            // negative values indicate a nearest match
+            var near = find<0?Math.Abs(find)-1:find;
+            // use custom formatter to get the string
+            return String.Format(
+                new HmsFormatter(), 
+                cutoff[cutoff.Keys[near]], 
+                owner.Days, 
+                owner.Hours, 
+                owner.Minutes, 
+                owner.Seconds);
+        }
+    }
+}

+ 0 - 4
Workbench/Processor/Processor.csproj

@@ -8,8 +8,4 @@
     <RootNamespace>Quadarax.Foundation.Core.Business.Processor</RootNamespace>
   </PropertyGroup>
 
-  <ItemGroup>
-    <Folder Include="Dependencies\" />
-  </ItemGroup>
-
 </Project>

+ 54 - 0
Workbench/Processor/Queue/ProcessQueue.cs

@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Quadarax.Foundation.Core.Business.Processor.Task;
+using Quadarax.Foundation.Core.Logging;
+using Quadarax.Foundation.Core.Object;
+
+namespace Quadarax.Foundation.Core.Business.Processor.Queue
+{
+    public class ProcessQueue : DisposableObject
+    {
+
+        public void Start()
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Stop()
+        {
+            throw new NotImplementedException();
+        }
+
+        public ITaskIdentifier CreateTask()
+        {
+
+        }
+        public ITaskItem GetTask(ITaskIdentifier id)
+        {
+
+        }
+        public ITaskItem[] GetTask(ITaskIdentifier[] ids)
+        {
+
+        }
+
+        public bool ContainsPendingTasks()
+        {
+
+        }
+        public bool ContainsProcessingTasks()
+        {
+
+        }
+        
+
+        protected override void OnDisposing()
+        {
+            throw new NotImplementedException();
+        }
+
+    }
+}

+ 21 - 0
Workbench/Processor/Task/ITaskItem.cs

@@ -34,6 +34,10 @@ public interface ITaskItem : ITaskIdentifier, ITimeTracked
     /// Time when task will be expired.
     /// </summary>
     public DateTime? ProcessingValidTo { get; }
+	/// <summary>
+	/// Defines single attempt timeout. If null, timeout is not used.
+	/// </summary>
+    public TimeSpan? AttemptTimeout { get; }
 	/// <summary>
 	/// Decremental counter of attempts to try process task.
 	/// </summary>
@@ -50,6 +54,11 @@ public interface ITaskItem : ITaskIdentifier, ITimeTracked
 	/// Latest attempt duration
 	/// </summary>
     public TimeSpan StatLastAttemptDuration { get; }
+
+	/// <summary>
+	/// Collection of task status changes history log items. Ordered by <see cref="ITaskStatusLogItem.Created"/> descending.
+	/// </summary>
+	public ITaskStatusLogItem[] StatusLog { get; }
     #endregion
 
 	#region *** Operations ***
@@ -81,9 +90,21 @@ public interface ITaskItem : ITaskIdentifier, ITimeTracked
     /// <summary>
     /// Resets task to initial state and sets <see cref="Status"/> to <see cref="ProcessStatusEnum.Pending"/>.
     /// Uses current validity to re-calculate <see cref="ProcessingValidFrom"/> and <see cref="ProcessingValidTo"/> to now + <see cref="postponeValid"/>.
+    /// <list type="bullet">
+    ///	<item><description>Allowed state: <see cref="ProcessStatusEnum.Attached"/>, <see cref="ProcessStatusEnum.ProcessedSucc"/>, <see cref="ProcessStatusEnum.ProcessedFail"/>, <see cref="ProcessStatusEnum.Paused"/></description></item>
+    ///	<item><description>Set state to: <see cref="ProcessStatusEnum.Pending"/></description></item>
+    /// </list>
+    /// <exception cref="InvalidTaskStateException">When task state is invalid for operation.</exception>
     /// </summary>
     /// <param name="reason">Reason to reset task.</param>
     /// <param name="postponeValid">Postpone current validity from now.</param>
     void Reset(string reason, TimeSpan postponeValid);
+
+    /// <summary>
+    /// Deletes task and sets <see cref="Status"/> to <see cref="ProcessStatusEnum.Deleted"/>.
+    /// </summary>
+    /// <param name="reason">Reason to delete current task.</param>
+    /// <param name="immediate">Flag is true, deletes task immediately (afters status change)</param>
+    void Delete(string reason, bool immediate = false);
 	#endregion
 }

+ 11 - 0
Workbench/Processor/Task/ITaskStatusLogItem.cs

@@ -0,0 +1,11 @@
+using Quadarax.Foundation.Core.Business.Processor.Enums;
+
+namespace Quadarax.Foundation.Core.Business.Processor.Task
+{
+    public interface ITaskStatusLogItem
+    {
+        public ProcessStatusEnum Status { get; }
+        public string Reason { get; }
+        public DateTime Created { get; }
+    }
+}

+ 142 - 0
Workbench/Processor/Task/TaskItem.cs

@@ -0,0 +1,142 @@
+using Quadarax.Foundation.Core.Business.Processor.Enums;
+using Quadarax.Foundation.Core.Business.Processor.Queue;
+using Quadarax.Foundation.Core.Logging;
+using Quadarax.Foundation.Core.Object;
+using Quadarax.Foundation.Core.Value.Extensions;
+
+namespace Quadarax.Foundation.Core.Business.Processor.Task
+{
+    internal class TaskItem : ITaskItem
+    {
+        #region *** Properties ***
+
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.Id"/>
+        /// </summary>
+        public long Id { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.QueueType"/>
+        /// </summary>
+        public ProcessQueueTypeEnum QueueType { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.Created"/>
+        /// </summary>
+        public DateTime Created { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.Changed"/>
+        /// </summary>
+        public DateTime? Changed { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.AffinityToken"/>
+        /// </summary>
+        public IAffinityToken AffinityToken { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.Reference"/>
+        /// </summary>
+        public string Reference { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.Status"/>
+        /// </summary>
+        public ProcessStatusEnum Status { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.ProviderClass"/>
+        /// </summary>
+        public string ProviderClass { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.Priority"/>
+        /// </summary>
+        public byte Priority { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.ProcessingValidFrom"/>
+        /// </summary>
+        public DateTime ProcessingValidFrom { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.ProcessingValidTo"/>
+        /// </summary>
+        public DateTime? ProcessingValidTo { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.AttemptsLeft"/>
+        /// </summary>
+        public int AttemptsLeft { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.AttemptTimeout"/>
+        /// </summary>
+        public TimeSpan? AttemptTimeout { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.StatStarted"/>
+        /// </summary>
+        public DateTime StatStarted { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.StatFinished"/>
+        /// </summary>
+        public DateTime StatFinished { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.StatLastAttemptDuration"/>
+        /// </summary>
+        public TimeSpan StatLastAttemptDuration { get; }
+        /// <summary>
+        /// <inheritdoc cref="ITaskItem.StatusLog"/>
+        /// </summary>
+        public ITaskStatusLogItem[] StatusLog => _statusLog.ToArray();
+
+        public TypedArgument[] Arguments => _arguments.ToArray(); 
+        #endregion
+
+        #region *** Private Fields ***
+        private readonly List<ITaskStatusLogItem> _statusLog = new();
+        private readonly List<TypedArgument> _arguments = new();
+        private ILog _log;
+        private ProcessQueue _parent; 
+        #endregion
+
+        #region *** Constructors ***
+        private TaskItem(ProcessQueue parent, long id, ProcessStatusEnum initialStatus, string reference, string source, TypedArgument[] initialArguments, byte priority, int attepts, TimeSpan? attemptTimeout, DateTime validFrom, DateTime? validTo, ITaskStatusLogItem[]? initialStatusLog):
+            this(parent, reference, source, initialArguments, priority, attepts, attemptTimeout, validFrom, validTo, initialStatusLog)
+        {
+            Id = id;
+            Status = initialStatus;
+        }
+        public TaskItem(ProcessQueue parent, string reference, string providerClass, TypedArgument[] initialArguments, byte priority, int attepts, TimeSpan? attemptTimeout, DateTime validFrom, DateTime? validTo, ITaskStatusLogItem[]? initialStatusLog)
+        {	   
+            _parent = parent ?? throw new ArgumentNullException(nameof(parent)); 
+            _log = new ConsoleLogger().GetLogger(GetType());      
+            Priority = priority;
+            Reference = reference;
+            ProviderClass = providerClass;
+            Arguments.Setup(initialArguments);
+            AttemptTimeout = attemptTimeout;
+            AttemptsLeft = attepts;
+            ProcessingValidFrom = validFrom;
+            ProcessingValidTo = validTo;
+            Created = DateTime.Now;
+            if (initialStatusLog != null)
+                _statusLog.Setup(initialStatusLog);
+            Status = ProcessStatusEnum.Pending; 
+            Id = long.MinValue;
+        }
+        #endregion
+
+        
+        #region *** Public Operations ***
+        public void Postpone(TimeSpan postponeInterval, string reason)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Stop(string reason, bool willPause = true, bool willFail = false)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Reset(string reason, TimeSpan postponeValid)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Delete(string reason, bool immediate = false)
+        {
+            throw new NotImplementedException();
+        }
+        #endregion
+    }
+}