diff --git a/PARR.DAL/Context/DataContext.cs b/PARR.DAL/Context/DataContext.cs index 6c7f2621..1a64080d 100644 --- a/PARR.DAL/Context/DataContext.cs +++ b/PARR.DAL/Context/DataContext.cs @@ -6,6 +6,7 @@ using PARR.DAL.Extensions; using PARR.DAL.Models; using PARR.DAL.Models.Job; using PARR.DAL.Models.Schedule; +using PARR.DAL.Models.Task; using PARR.DAL.Models.Unit; namespace PARR.DAL.Context @@ -117,6 +118,15 @@ namespace PARR.DAL.Context #endregion + #region Tasks + + public DbSet Tasks { get; set; } + public DbSet TaskStatus { get; set; } + public DbSet TaskTypes { get; set; } + public DbSet TaskErrors { get; set; } + + #endregion + protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -555,6 +565,35 @@ namespace PARR.DAL.Context #endregion + + #region TaskType + + modelBuilder.Entity(f => + { + f.HasData(new TaskType[] + { + new() { Code = TaskTypeEnum.Workload, Name = TaskTypeEnum.Workload.ToString(), Description = "Формирование данных для отчетности - Загруженность", MaxRetries = 2 } + } + ); + }); + + #endregion + + #region TaskStatus + + modelBuilder.Entity(f => + { + f.HasData(new PARR.DAL.Models.Task.TaskStatus[] + { + new(){Code=TaskTaskStatusEnum.Wait, Name=TaskTaskStatusEnum.Wait.ToString(), Description="Ожидание"}, + new(){Code=TaskTaskStatusEnum.Processing, Name=TaskTaskStatusEnum.Processing.ToString(), Description="В работе"}, + new(){Code=TaskTaskStatusEnum.Success, Name=TaskTaskStatusEnum.Success.ToString(), Description="Выполнено успешно"}, + new(){Code=TaskTaskStatusEnum.Error, Name=TaskTaskStatusEnum.Error.ToString(), Description="Ошибка"} + }); + }); + + #endregion + } //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) diff --git a/PARR.DAL/Context/DataContextSettings.cs b/PARR.DAL/Context/DataContextSettings.cs index e0539407..19424f2b 100644 --- a/PARR.DAL/Context/DataContextSettings.cs +++ b/PARR.DAL/Context/DataContextSettings.cs @@ -18,5 +18,11 @@ /// Расписание регламентных работ /// public const string Schedule = "schedule"; + + + /// + /// Управление очередями + /// + public const string Task = "task"; } } diff --git a/PARR.DAL/Contracts/TaskStatusEnum.cs b/PARR.DAL/Contracts/TaskStatusEnum.cs index d33eea7b..cb364f4a 100644 --- a/PARR.DAL/Contracts/TaskStatusEnum.cs +++ b/PARR.DAL/Contracts/TaskStatusEnum.cs @@ -1,5 +1,7 @@ namespace PARR.DAL.Contracts { + //TODO: Надо это переименовать в RobotTaskStatusEnum + /// /// Статус задания на синхронизацию /// diff --git a/PARR.DAL/Contracts/TaskTaskStatusEnum.cs b/PARR.DAL/Contracts/TaskTaskStatusEnum.cs new file mode 100644 index 00000000..7377435a --- /dev/null +++ b/PARR.DAL/Contracts/TaskTaskStatusEnum.cs @@ -0,0 +1,30 @@ +namespace PARR.DAL.Contracts +{ + // TODO: Сначала надо переименовать TaskStatusEnum -> RobotTaskStatusEnum, а потом TaskTaskStatusEnum -> TaskStatusEnum + + /// + /// Статус задач Task + /// + public enum TaskTaskStatusEnum + { + /// + /// Ожидание + /// + Wait=10, + + /// + /// В работе + /// + Processing = 20, + + /// + /// Выполнено успешно + /// + Success = 30, + + /// + /// Ошибка + /// + Error = 40 + } +} diff --git a/PARR.DAL/Contracts/TaskTypeEnum.cs b/PARR.DAL/Contracts/TaskTypeEnum.cs new file mode 100644 index 00000000..2f163d1b --- /dev/null +++ b/PARR.DAL/Contracts/TaskTypeEnum.cs @@ -0,0 +1,13 @@ +namespace PARR.DAL.Contracts +{ + /// + /// Типы заданий + /// + public enum TaskTypeEnum + { + /// + /// Загруженность + /// + Workload = 0, + } +} diff --git a/PARR.DAL/Models/Task/Task.cs b/PARR.DAL/Models/Task/Task.cs new file mode 100644 index 00000000..9ca5a78c --- /dev/null +++ b/PARR.DAL/Models/Task/Task.cs @@ -0,0 +1,47 @@ +using Microsoft.EntityFrameworkCore; +using PARR.DAL.Context; +using PARR.DAL.Contracts; +using PARR.DAL.Models.Base; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace PARR.DAL.Models.Task +{ + [Table("Tasks", Schema = DataContextSettings.Task)] + [Comment("Таблица заданий")] + public class Task : IBase + { + [Key] + public Guid Id { get; set; } + + public DateTimeOffset DateCreated { get; set; } + + public DateTimeOffset? DateModified { get; set; } + + public TaskTypeEnum TypeCode { get; set; } + + public TaskTaskStatusEnum StatusCode { get; set; } + + public string? Payload { get; set; } + + /// + /// Кол-во попыток + /// + public int RetryCount { get; set; } + + /// + /// Дата завершения (устанавливается или когда Успех или когда Ошибка) + /// + public DateTimeOffset? ProcessedAt { get; set; } + + + + [ForeignKey(nameof(TypeCode))] + public TaskType? TaskType { get; set; } + + [ForeignKey(nameof(StatusCode))] + public TaskStatus? TaskStatus { get; set; } + + public ICollection TaskErrors { get; set; } = new HashSet(); + } +} diff --git a/PARR.DAL/Models/Task/TaskError.cs b/PARR.DAL/Models/Task/TaskError.cs new file mode 100644 index 00000000..51709574 --- /dev/null +++ b/PARR.DAL/Models/Task/TaskError.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore; +using PARR.DAL.Context; +using PARR.DAL.Models.Base; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace PARR.DAL.Models.Task +{ + [Table("Errors", Schema = DataContextSettings.Task)] + [Comment("Таблица ошибок заданий")] + public class TaskError : IBase + { + [Key] + public Guid Id { get; set; } + + public DateTimeOffset DateCreated { get; set; } + + [NotMapped] + public DateTimeOffset? DateModified { get; set; } + + public Guid TaskId { get; set; } + + public int AttemptNumber { get; set; } + + public required string ErrorMessage { get; set; } + + public string? StackTrace { get; set; } + + [ForeignKey(nameof(TaskId))] + public Task? Task { get; set; } + } +} diff --git a/PARR.DAL/Models/Task/TaskStatus.cs b/PARR.DAL/Models/Task/TaskStatus.cs new file mode 100644 index 00000000..4879bf7b --- /dev/null +++ b/PARR.DAL/Models/Task/TaskStatus.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore; +using PARR.DAL.Context; +using PARR.DAL.Contracts; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace PARR.DAL.Models.Task +{ + [Table("Statuses", Schema = DataContextSettings.Task)] + [Comment("Таблица статусов заданий")] + public class TaskStatus + { + [Key] + public TaskTaskStatusEnum Code { get; set; } + + public required string Name { get; set; } + + public required string Description { get; set; } + + + public ICollection Tasks { get; set; } = new HashSet(); + } +} diff --git a/PARR.DAL/Models/Task/TaskType.cs b/PARR.DAL/Models/Task/TaskType.cs new file mode 100644 index 00000000..fc61b5a6 --- /dev/null +++ b/PARR.DAL/Models/Task/TaskType.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore; +using PARR.DAL.Context; +using PARR.DAL.Contracts; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace PARR.DAL.Models.Task +{ + [Table("Types", Schema = DataContextSettings.Task)] + [Comment("Таблица типов заданий")] + public class TaskType + { + [Key] + public TaskTypeEnum Code { get; set; } + + public required string Name { get; set; } + + public required string Description { get; set; } + + /// + /// Максимальное кол-во попыток + /// + public int MaxRetries { get; set; } + + + public ICollection Tasks { get; set; } = new HashSet(); + } +} diff --git a/PARR.DAL/ParrDalInstaller.cs b/PARR.DAL/ParrDalInstaller.cs index f858bb7a..758a30e4 100644 --- a/PARR.DAL/ParrDalInstaller.cs +++ b/PARR.DAL/ParrDalInstaller.cs @@ -18,10 +18,12 @@ using PARR.DAL.Services.Implementation; using PARR.DAL.Services.Implementations; using PARR.DAL.Services.Implementations.Job; using PARR.DAL.Services.Implementations.Schedule; +using PARR.DAL.Services.Implementations.Task; using PARR.DAL.Services.Implementations.Unit; using PARR.DAL.Services.Interfaces; using PARR.DAL.Services.Interfaces.Job; using PARR.DAL.Services.Interfaces.Schedule; +using PARR.DAL.Services.Interfaces.Task; using PARR.DAL.Services.Interfaces.Unit; using PARR.DAL.Settings; using StackExchange.Redis; @@ -144,6 +146,13 @@ namespace PARR.DAL #endregion + #region Task + + services.AddTransient(); + services.AddTransient(); + + #endregion + //services.AddTransient(); #region NextRun Services diff --git a/PARR.DAL/Services/Implementations/Task/TaskErrorService.cs b/PARR.DAL/Services/Implementations/Task/TaskErrorService.cs new file mode 100644 index 00000000..5fe91e66 --- /dev/null +++ b/PARR.DAL/Services/Implementations/Task/TaskErrorService.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using PARR.DAL.Context; +using PARR.DAL.Models.Task; +using PARR.DAL.Services.Abstracts; +using PARR.DAL.Services.Interfaces.Task; + +namespace PARR.DAL.Services.Implementations.Task +{ + internal class TaskErrorService : BaseService, ITaskErrorService + { + private readonly DataContext dataContext; + + protected override DbSet EntitySet => dataContext.TaskErrors; + + protected override DataContext EntitiContext => dataContext; + + public TaskErrorService(DataContext dataContext, ILogger logger): base(logger) + { + this.dataContext = dataContext; + } + } +} diff --git a/PARR.DAL/Services/Implementations/Task/TaskService.cs b/PARR.DAL/Services/Implementations/Task/TaskService.cs new file mode 100644 index 00000000..adf0ef2d --- /dev/null +++ b/PARR.DAL/Services/Implementations/Task/TaskService.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using PARR.DAL.Context; +using PARR.DAL.Services.Abstracts; +using PARR.DAL.Services.Interfaces.Task; + +namespace PARR.DAL.Services.Implementations.Task +{ + internal class TaskService : BaseService, ITaskService + { + private readonly DataContext dataContext; + + protected override DbSet EntitySet => dataContext.Tasks; + + protected override DataContext EntitiContext => dataContext; + + public TaskService(DataContext dataContext, ILogger logger) : base(logger) + { + this.dataContext = dataContext; + } + + + // метод атомарного взятия в работу + } +} diff --git a/PARR.DAL/Services/Interfaces/Task/ITaskErrorService.cs b/PARR.DAL/Services/Interfaces/Task/ITaskErrorService.cs new file mode 100644 index 00000000..46345ad4 --- /dev/null +++ b/PARR.DAL/Services/Interfaces/Task/ITaskErrorService.cs @@ -0,0 +1,9 @@ +using PARR.DAL.Models.Task; +using PARR.DAL.Services.Interfaces.Base; + +namespace PARR.DAL.Services.Interfaces.Task +{ + public interface ITaskErrorService : IBaseService + { + } +} diff --git a/PARR.DAL/Services/Interfaces/Task/ITaskService.cs b/PARR.DAL/Services/Interfaces/Task/ITaskService.cs new file mode 100644 index 00000000..dc2878ed --- /dev/null +++ b/PARR.DAL/Services/Interfaces/Task/ITaskService.cs @@ -0,0 +1,8 @@ +using PARR.DAL.Services.Interfaces.Base; + +namespace PARR.DAL.Services.Interfaces.Task +{ + public interface ITaskService : IBaseService + { + } +}