using System; using System.Collections.Generic; using Microsoft.Extensions.Logging; using Quadarax.Foundation.Core.Business.Enums; using Quadarax.Foundation.Core.Business.Interface; using Quadarax.Foundation.Core.Data.Interface.Domain; using Quadarax.Foundation.Core.Data.Interface.Repository; using Quadarax.Foundation.Core.Thread; using ILogger = Quadarax.Foundation.Core.Logging.ILogger; namespace Quadarax.Foundation.Core.Business { public abstract class AbstractWorkerService : AbstractRepositoryService where TRepository: IRepository where TWorker : AbstractWorker, new() { #region *** Private fields *** private IList> _workers = new List>(); private IWorkerSettings _wrkSettings; private object _lockTransient = null; #endregion #region *** Properties *** protected abstract string Name { get; } #endregion #region *** Constructors *** protected AbstractWorkerService(IWorkerSettings workerSettings, TRepository repository, IContext currentContext, ILoggerFactory logger) : base(repository, currentContext, logger) { State = ServiceStateEnum.Initializing; _wrkSettings = workerSettings ?? throw new ArgumentNullException(nameof(workerSettings)); InitInternal(); } #endregion #region *** Public Operations *** public void Start() { lock (_lockTransient) { _lockTransient = new object(); for(var a=0;a<_wrkSettings.WorkerCount;a++) { var wrk = (TWorker)Activator.CreateInstance(typeof(TWorker),$"{Name}#{a}", new RepoWorkerContext(Repository), (ILogger)LoggerFactory.CreateLogger(this.GetType())); var info = new WorkerStatusInfo(wrk?.Name); _workers.Add(new Tuple(info, wrk)); wrk?.Start(); info.SetStart(); info.SetIterations(wrk.CurrentThreadId, wrk.IterationCount); } _lockTransient = null; State = ServiceStateEnum.Online; } } public void Stop() { lock (_lockTransient) { _lockTransient = new object(); foreach (var wrk in _workers) { wrk.Item2.Stop(); wrk.Item1.SetStop(); wrk.Item1.SetIterations(wrk.Item2.CurrentThreadId, wrk.Item2.IterationCount); } _lockTransient = null; State = ServiceStateEnum.Offline; } } #endregion #region *** Private Operations *** private void InitInternal() { } #endregion #region *** Nested Classes *** private class RepoWorkerContext : IWorkerContext { public TRepository Repository { get; } public RepoWorkerContext(TRepository repository) { Repository = repository ?? throw new ArgumentNullException(nameof(repository)); } } #endregion } public abstract class AbstractWorkerService : AbstractWorkerService where TRepository : IRepository where TRepository1 : IRepository where TWorker : AbstractWorker, new() { protected TRepository1 Repository1 { get; } protected AbstractWorkerService(IWorkerSettings workerSettings,TRepository1 repository1, TRepository repository, IContext currentContext, ILoggerFactory logger) : base(workerSettings, repository, currentContext, logger) { Repository1 = repository1 ?? throw new ArgumentNullException(nameof(repository1)); } } public abstract class AbstractWorkerService : AbstractWorkerService where TRepository : IRepository where TRepository1 : IRepository where TRepository2 : IRepository where TWorker : AbstractWorker, new() { protected TRepository2 Repository2 { get; } protected AbstractWorkerService(IWorkerSettings workerSettings,TRepository2 repository2, TRepository1 repository1, TRepository repository, IContext currentContext, ILoggerFactory logger) : base(workerSettings,repository1, repository, currentContext, logger) { Repository2 = repository2 ?? throw new ArgumentNullException(nameof(repository2)); } } public abstract class AbstractWorkerService : AbstractWorkerService where TRepository : IRepository where TRepository1 : IRepository where TRepository2 : IRepository where TRepository3 : IRepository where TWorker : AbstractWorker, new() { protected TRepository3 Repository3 { get; } protected AbstractWorkerService(IWorkerSettings workerSettings,TRepository3 repository3, TRepository2 repository2, TRepository1 repository1, TRepository repository, IContext currentContext, ILoggerFactory logger) : base(workerSettings, repository2, repository1, repository, currentContext, logger) { Repository3 = repository3 ?? throw new ArgumentNullException(nameof(repository3)); } } public abstract class AbstractWorkerService : AbstractWorkerService where TRepository : IRepository where TRepository1 : IRepository where TRepository2 : IRepository where TRepository3 : IRepository where TRepository4 : IRepository where TWorker : AbstractWorker, new() { protected TRepository4 Repository4 { get; } protected AbstractWorkerService(IWorkerSettings workerSettings,TRepository4 repository4, TRepository3 repository3, TRepository2 repository2, TRepository1 repository1, TRepository repository, IContext currentContext, ILoggerFactory logger) : base(workerSettings,repository3,repository2,repository1, repository, currentContext, logger) { Repository4 = repository4 ?? throw new ArgumentNullException(nameof(repository4)); } } }