【问题标题】:How to design a processor that loads objects from a runtime configuration如何设计从运行时配置加载对象的处理器
【发布时间】:2021-03-08 23:07:35
【问题描述】:

我正在实施调度程序。作为其核心逻辑的一部分,它处理自定义对象Schedule。基本上它会遍历一系列时间表并尝试处理它。问题是,谁创建了 Schedule 需要使用 ISchedule 接口将其注册到容器中。然后我的调度程序从容器中提取所有 ISchedule 引用。到目前为止,这是可行的,但它没有加载调度运行时的灵活性。我可以采用什么设计和实现来实现可以加载这些调度运行时的调度器。我给出了一些示例代码。

我想到的事情是让开发人员编写调度程序的 json 表示并将其放入配置中或实现一个端点,将该配置返回给调度程序。但是我可以避免这种情况吗?我希望调度程序完全不依赖开发人员代码。

【问题讨论】:

    标签: c# architecture scheduled-tasks system software-design


    【解决方案1】:

    您可以使用工厂来注册有关计划课程的信息。并通过 Id 查找调度来动态更改调用间隔。 您在容器中注册:

    public interface ISchedule
    {
        public string Id { get; set; }
        public TimeSpan Interval { get; set; }
    
        public DateTime? LastExecution { get; set; }
    
        public bool CanStart { get; }
    
        void Start();
        void Stop();
    }
    
    public sealed class Schedule : ISchedule
    {
        public string Id { get; set; }
        public TimeSpan Interval { get; set; }
        public DateTime? LastExecution { get; set; }
        public bool CanStart {
            get
            {
                lock (_sync)
                {
                    return !LastExecution.HasValue || LastExecution.Value.Add(Interval) >= DateTime.UtcNow;
                }
            }
        }
    
        private readonly object _sync = new object();
        
        public void Start()
        {
            lock (_sync)
            {
                if (!LastExecution.HasValue || LastExecution.Value.Add(Interval) >= DateTime.UtcNow)
                {
                    // DO WORK
                    LastExecution = DateTime.UtcNow;
                }
            }
            
        }
    
        public void Stop()
        {
            throw new NotImplementedException();
        }
    }
    
    public interface IScheduleFactory
    {
        ISchedule Create();
    }
    
    public sealed class ScheduleFactory: IScheduleFactory
    {
        private readonly IScheduleManager _manager;
    
        public ScheduleFactory(IScheduleManager manager)
        {
            _manager = manager;
        }
    
        public ISchedule Create()
        {
            var schedule = new Schedule();
            _manager.Register(schedule);
    
            return schedule;
        }
    }
    
    public interface IScheduleManager
    {
        void Register(ISchedule schedule);
        ISchedule Get(string id);
    
        void Start();
        void Stop();
    
    }
    public sealed class ScheduleManager : IScheduleManager
    {
        private readonly Dictionary<string,ISchedule> _items =  new Dictionary<string, ISchedule>();
        private readonly object _sync = new object();
        public void Register(ISchedule schedule)
        {
            lock (_sync)
            {
                if (_items.ContainsKey(schedule.Id))
                    _items.Add(schedule.Id, schedule);
            }
            
        }
    
        public ISchedule Get(string id)
        {
            lock (_sync)
            {
                if (_items.ContainsKey(id))
                    return _items[id];
            }
    
            return null;
        }
    
        private bool _isStart;
        public void Start()
        {
            _isStart = true;
            while (_isStart)
            {
                ISchedule[] array = null;
                lock (_sync)
                {
                    array = _items.Values.ToArray();
                }
    
                foreach (var schedule in array)
                {
                    if (schedule.CanStart)
                        Task.Factory.StartNew(()=>schedule.Start());
                }
            }
            
        }
    
        public void Stop()
        {
            _isStart = false;
        }
    }
    

    【讨论】:

    • 我应该向开发人员提供哪些基础设施来在那里注册类。目前容器在调度程序的同一个实例中运行,如果我不断轮询它每次都会得到相同的值。
    • 可以在IScheduleManager中添加Remove方法
    • 开发人员应该添加一个新的计划并完成它,而我正在运行的实例需要获取新的计划。将时间表存储在数据库存储中是否可行?
    • 开发者可以使用Schedule Get(string id)方法获取日程信息,改变Schedule对象的状态。他们可以进行基于事件或计划的实现,从数据库中读取数据
    猜你喜欢
    • 2021-07-09
    • 2011-06-23
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 2018-03-05
    相关资源
    最近更新 更多