ProcessingWorker.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using Quadarax.Application.QLiberace.Base.Services;
  2. using Quadarax.Application.QLiberace.Processor.Entities;
  3. using Quadarax.Application.QLiberace.Processor.Enums;
  4. using Quadarax.Application.QLiberace.Processor.Repositories;
  5. using Quadarax.Application.QLiberace.Processor.Settings;
  6. using Quadarax.Foundation.Core.Business;
  7. using Quadarax.Foundation.Core.Logging;
  8. using Quadarax.Foundation.Core.Thread;
  9. namespace Quadarax.Application.QLiberace.Processor.Workers
  10. {
  11. internal class ProcessingWorker : QlbrcProcessorWorker
  12. {
  13. #region *** Private fields ***
  14. // TODO: may be shift to ProcessorSetting
  15. private const int CN_ITEMS_PER_CYCLE = 1;
  16. #endregion
  17. #region *** Properties ***
  18. #endregion
  19. #region *** Constructor ***
  20. public ProcessingWorker(IWorkerContext context, SettingsService? srvSettings, IQLogger logger) : base(context, srvSettings, srvSettings?.GetSettings<ProcessorSetting>(Base.Constants.Modules.Processor.Code)?.Value?.ProcessingWorkerPwi!, logger)
  21. {
  22. }
  23. #endregion
  24. #region *** Private Operations ***
  25. protected override Task DoIteration(IWorkerContext context)
  26. {
  27. var ctx = (RepoWorkerContext)context;
  28. // Get worker name
  29. var workerName = GetName(Settings.ProcessingWorkerPwi);
  30. var repoProcessing = ctx.GetRepository<RepoProcessingQueue>();
  31. // 1. Continue to work on already processing entries in ProcessQ (paused, tryout failed)
  32. // 2. If still available packet, lock pending entries in PendingQ
  33. // 3. Move locked entries to ProcessQ
  34. var processings = FetchFromQueue(ctx.GetRepository<RepoPendingQueue>(), ctx.GetRepository<RepoProcessingQueue>());
  35. foreach (var processing in processings)
  36. {
  37. processing.Started = DateTime.Now;
  38. processing.AffinityWorker = workerName;
  39. processing.Status = QueueStatusEnum.Working;
  40. repoProcessing.Set(processing);
  41. }
  42. // 4. Start to process
  43. // 5. Decrement attempt
  44. // 6. Move processed entries to DoneQ or FailedQ
  45. }
  46. private IEnumerable<ProcessingQueue> FetchFromQueue(RepoPendingQueue repoPending, RepoProcessingQueue repoProcessing)
  47. {
  48. if (repoPending == null) throw new ArgumentNullException(nameof(repoPending));
  49. if (repoProcessing == null) throw new ArgumentNullException(nameof(repoProcessing));
  50. // Get worker name
  51. var workerName = GetName(Settings.ProcessingWorkerPwi);
  52. // Get from pending queue
  53. var pendings = repoPending.GetPending(CN_ITEMS_PER_CYCLE).ToArray();
  54. // Assign pending
  55. foreach (var pending in pendings)
  56. {
  57. // Set Assigned
  58. pending.Status = QueueStatusEnum.Assigned;
  59. pending.AffinityWorker = workerName;
  60. // Create processing entry from pending entry
  61. var processing = repoProcessing.NewFromPending(pending);
  62. // Delete pending (mark it)
  63. pending.Status = QueueStatusEnum.Deleted;
  64. repoPending.Set(pending);
  65. }
  66. // Try to load forgot items from previous start
  67. var processings = repoProcessing.GetAssignedOrWorking(workerName, CN_ITEMS_PER_CYCLE).ToArray();
  68. return processings;
  69. }
  70. #endregion
  71. }
  72. }