码农技术炒股之路——任务管理器
系统任务和普通任务都是通过任务管理器调度的。它们的区别是:系统任务在程序运行后即不会被修改,而普通任务则会被修改。(转载请指明出于breaksoftware的csdn博客)
为什么要有这样的设计?因为我希望它是一个可以不用停止服务就可以更新相关配置的系统。比如我们现在要加一个普通任务,我们只要修改下普通任务配置文件即可。再比如我们需要修改数据库中表结构,我们也不用停止服务修改代码来保证数据格式的一致性。
我们程序需要知道配置文件是否被修改。如何去做?一种方法是借用一些系统方法监听相应配置文件的修改,一旦文件有变化,马上通知我们的主程序去处理。另一种则是采用轮询检查机制,即定期去生成差异结果。为了不让这个系统更加复杂,我选择后者。而它就是我所谓的系统任务。
不管是系统任务还是普通任务,实现的类都要继承于job_base
from abc import ABCMeta,abstractmethod
class job_base:__metaclass__ = ABCMeta@abstractmethoddef run(self):pass
有这个限制主要是为了保证每个任务都是run方法。调度框架将执行该方法以完成任务执行。
在《码农技术炒股之路——架构和设计》一文中,介绍了我们将基于APScheduler实现任务调度功能。首先我们需要启动BackgroundScheduler对象
from apscheduler.schedulers.background import BackgroundScheduler@singleton
class job_center():def __init__(self):self._sched = Noneself._job_conf_path = ""self._job_id_handle = {}self._static_job_id_handle = {}def start(self):self._sched = BackgroundScheduler()self._sched.start()
当我们需要加入任务时,则调用下面这个方法
def add_jobs(self, jobs_info, is_static = False):if None == self._sched:LOG_WARNING("job center must call start() first")returnfor (job_name,job_info) in jobs_info.items():if is_static and job_name in self._static_job_id_handle.keys():continuejob_type = job_info["type"]class_name = job_info["class"]job_handle = self._get_obj(class_name)if is_static:self._static_job_id_handle[job_name] = job_handleelse:self._job_id_handle[job_name] = job_handlecmd = "self._sched.add_job(job_handle.run, job_type, id = job_name"params = self._join_params(job_info)if 0 != len(params):cmd += " , "cmd += paramscmd += ")"#print cmdeval(cmd)
jobs_info保存的是任务配置文件中任务信息,我们看个样例
[update_share_base_info]
type=cron
class=update_stock_base_info
day_of_week=1-5
hour=9
minute=30
second=10
timezone = Asia/Shanghai
这个配置中除了type和class,其他都是APScheduler框架中add_job方法中的参数。上面配置意思是:以上海时间,从周一到周五,早上9点30分10秒执行一次。
add_jobs中通过class字段,获取该class对应的一个对象
def _get_obj(self, _cls_name): _packet_name = _cls_name _module_home = __import__(_packet_name,globals(),locals(),[_cls_name])obj = getattr(_module_home,_cls_name) class_obj = obj()return class_obj
这儿又要提到我之前特别强调过的单例使用方式。经过测试,《码农技术炒股之路——配置管理器、日志管理器》中单例的实现可以保证上面这个方法获取的是同一个对象,而网上其他单例模式则不行。
获取对象后,我们要组装出要执行的命令。cmd = "self._sched.add_job(job_handle.run, job_type, id = job_name"中job_handle就是上面获取的对象,而run则是每个job都要有的方法。这也是为什么要求每个任务类都要继承于job_base的原因。
之后调用_join_params将配置文件中其他信息组装成参数拼接出完整命令
def _join_params(self, job_info):params = ""param = ""job_type = job_info["type"]for key in job_info.keys():if key in conf_keys.job_conf_info_dict[job_type]:if 0 != len(params):params += ' , 'value = job_info[key]if value.isdigit():param = key + " = " + valueelse:param = key + " = '" + value + "'"if 0 != len(param):params += paramreturn params
如此我们配置中的任务就会被加入到APScheduler调度队列中。
我们再看下如何删除一个任务
def remove_jobs(self, jobs_info):if None == self._sched:LOG_WARNING("job center must call start() first")returnfor job_name in jobs_info.keys():self._sched.remove_job(job_name)self._job_id_handle.pop(job_name)
第7行通过任务名称在APScheduler中把任务删除。第8行将任务对应的对象从列表中删除。为什么要使用_job_id_handle去保存这些任务对象呢?因为如果不在一个更大的生命周期内保存它,它就会被认为是一个局部变量,从而被释放,导致之后APScheduler再也调用不了它。
我们看个管理普通任务的系统任务代码
@singleton
class j_load_job_conf(job_base):def __init__(self):self._pre_jobs_info = {}self._frame_conf_inst = scheduler_frame_conf_inst()self._job_center = job_center()def run(self):section_name = "strategy_job"option_name = "conf_path"if False == self._frame_conf_inst.has_option(section_name, option_name):LOG_WARNING("no %s %s" % (section_name, option_name))returnconf_path = self._frame_conf_inst.get(section_name, option_name)LOG_DEBUG("Load %s %s %s" % (section_name, option_name, conf_path))job_conf_parser_obj = job_conf_parser()jobs_info = job_conf_parser_obj.parse(conf_path)self._execute_jobs(jobs_info)def _execute_jobs(self, jobs_info):add_dict = {}remove_dict = {}modify_dict = {}frame_tools.dict_diff(jobs_info, self._pre_jobs_info, add_dict, remove_dict, modify_dict)add_jobs_info = dict(add_dict, **modify_dict)remove_jobs_info = {}for item in modify_dict.keys():remove_jobs_info[item] = self._pre_jobs_info[item]LOG_INFO("add jobs %s" % (json.dumps(add_jobs_info)))LOG_INFO("remove jobs %s" % (json.dumps(remove_jobs_info)))if 0 == len(add_jobs_info) and 0 == len(remove_jobs_info):returnself._pre_jobs_info = jobs_infoself._job_center.remove_jobs(remove_jobs_info)self._job_center.add_jobs(add_jobs_info)
run方法将会定期执行。它会从固定目录读取普通任务配置文件信息。然后在_execute_jobs方法中,通过和上一次读取的任务信息对比,生成三个字典:需要删除的任务、需要新增的任务和需要修改的任务。需要修改的任务将变成先删除后新增的方式实现修改。所以最后操作的将是两个字段信息。
普通任务本文就不介绍了,之后介绍的每个抓取和离线计算业务都是普通任务。
相关文章:
面对新型肺炎疫情,AI能做什么?
作者 | 马超出品 | AI科技大本营(ID:rgznai100)根据最新的新型冠状病毒疫情通报,截至1月30日24时,国家卫生健康委公布确诊病例9692例,重症病例1527例,累计死亡病例213例,另有疑似病例15238例。为…

大家帮忙.谢谢!..(急急急急急)
大家帮忙.谢谢!..(急急急急急) Delphi / Windows SDK/APIhttp://www.delphi2007.net/DelphiDB/html/delphi_20061218224617231.htmlprocedure TForm1.Button4Click(Sender: TObject); var P : pstring; i, j : integer; begin GetMem(p, sizeof(stri…

HDU4866 Shooting (要持久段树)
意甲冠军: 给你一些并行x行轴。总是询问坐标x的顶部之前,k一个段高度,。标题是必须在线。思路: 首先要会可持久化线段树(又称主席树和函数式线段树)。不会的能够去做下POJ 2104。 把全部线段高度离散化,作为结点建线段…
C++过去的这一年
作者 | Bartek译者 | 苏本如,责编 | 屠敏出品 | CSDN(ID:CSDNnews)【导读】本文旨在让我们回顾 C 2019年里的变化和发展!我们将重点关注本年度里 C 上发生的重大事件,标准的发展,工具的变化等等…
码农技术炒股之路——抓取股票基本信息、实时交易信息、主力动向信息
从本节开始,我们开始介绍各个抓取和备份业务。(转载请指明出于breaksoftware的csdn博客) 因为我们数据库很多,数据库中表也很多,所以我们需要一个自动检测并创建数据库和表的功能。在《码农技术炒股之路——数据库管理…

TemplateBuilder
http://msdn.microsoft.com/zh-cn/vstudio/system.web.ui.templatebuilder_members(VS.85).aspx TemplateBuilder 成员TemplateBuilder 成员支持在生成模板及其包含的子控件时使用的页分析器。 下表列出了由 TemplateBuilder 类型公开的成员。 公共构造函数 名称 说明 Templat…

【iOS UI】iOS 9 GUI 资源分享
分享的内容包括一个【DesignCode-iOS-9-GUI】Sketch 文件, 和苹果官方释出的【SF-UI、SF-Compact】两种字体的安装包。 以上内容是正版、免费的 <a href "https://itunes.apple.com/cn/app/sketch-3/id852320343?mt12">Sketch</a> 是收费软…
反向R?削弱显著特征为细粒度分类带来提升 | AAAI 2020
作者 | VincentLee来源 | 晓飞的算法工程笔记导读:论文提出了类似于dropout作用的diversification block,通过抑制特征图的高响应区域来反向提高模型的特征提取能力,在损失函数方面,提出专注于top-k类别的gradient-boosting loss来…

C#初学——doWhile
继续上面的学习,这次的是流程控制,用dowhile,代码如下,还是用语言选择来作为事例的。using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication9 { class Program { static void Main(s…

码农技术炒股之路——实时交易信息、主力动向信息分库备份
一般来说,一个股票信息应该保存在一张表中。但是由于我机器资源限制,且我希望尽快频率的抓取数据。所以每天我将所有股票的实时交易信息放在daily_temp库中的一个以日期命名的表中。主力动向信息也是如此。但是盘后分析股票时,我们会以单只股…

数据预处理(完整步骤)
原文:http://dataunion.org/5009.html 一:为什么要预处理数据?(1)现实世界的数据是肮脏的(不完整,含噪声,不一致)(2)没有高质量的数据,…

码农技术炒股之路——抓取日线数据、计算均线和除权数据
日线数据是股票每日收盘后的信息。这块数据不用实时抓取,所以并不占用宝贵的交易时间的资源。于是我们抓取完数据后直接往切片后的数据库中保存。(转载请指明出于breaksoftware的csdn博客) 抓取日线数据 我们先要获取今天有交易信息的股票代…

茫茫碌碌的日子
一连很好多天,都在为公司数据库基础构架升级的事情忙活着。升级的事情还是比较棘手的。需要升级硬件服务器,相关的存储,操作系统,数据库产品,涉及面非常多。当然烦心的事情就很多。作为线上生产系统,升级和…
Python PK C++,究竟谁更胜一筹?
作者 | Farhad Malik译者 | 弯月,编辑 | 屠敏来源 | CSDN(ID:CSDNnews)在编程生涯的早期阶段,我参与过一款C数学优化应用程序的开发,这个程序对性能的要求很高。至今我依然记得那段艰难的经历。在那个项目中…

oracle--查看表空间大小以及修改表空间大小
为什么80%的码农都做不了架构师?>>> 一.修改表空间大小 解决以上问题的办法:通过增大表空间即可解决,如下: Sql代码 使用dba用户登陆 sqlplus / as sysdba; 执行如下命令: SQL >…
同步、异步、堵塞、非堵塞和函数调用及I/O之间的组合概念
在我们工作和学习中,经常会接触到“同步”、“异步”、“堵塞”和“非堵塞”这些概念,但是并不是每个人都能将它们的关系和区别说清楚。本文将对这些基本概念进行讨论,以期让大家有更清楚的认识。(转载请指明出于breaksoftware的c…
“抗击”新型肺炎!阿里达摩院研发AI算法,半小时完成疑似病例基因分析
利用技术辅助抗击疫情,阿里巴巴、百度等科技巨头各显身手。此前,AI科技大本营采访报道了阿里达摩院《数十名工程师作战5天,阿里达摩院连夜研发智能疫情机器人》一文,后者为了解决客服人力不足的局面,快速响应政府需求开…

反编译工具jad简单用法
反编译工具jad简单用法 下载地址:[url]http://58.251.57.206/down1?cidB99584EFA6154A13E5C0B273C3876BD4CC8CE672&t2&fmt&usrinput[/url]反编译工具jad &dt2002000一. 不用安装,只要解压就行(有这样两个文件jad.exe&#x…
ubuntu 系统设置bugzilla制
随着时间的推移。在大脑中形成的记忆总会慢慢的淡去。人的记忆力就是这样。所以最好的办法就是形成博客去记录下来,一方面给自己以后回想用。一方面也算是自己的一个积累。所以一旦选择了一个行业,最好不要轻 易转行,由于非常多知识须要不断的…
静态分析C语言生成函数调用关系的利器——cflow
除了《静态分析C语言生成函数调用关系的利器——calltree》一文中介绍的calltree,我们还可以借助cflow辅助我们阅读理解代码。(转载请指明出于breaksoftware的csdn博客) cflow的说明和安装cflow是一款静态分析C语言代码的工具,通过…
我在MongoDB年终大会上获二等奖文章:由数据迁移至MongoDB导致的数据不一致问题及解决方案...
作者 | 上海小胖来源 | Python专栏(ID:xpchuiit)故事背景企业现状2019年年初,我接到了一个神秘电话,电话那头竟然准确的说出了我的昵称:上海小胖。我想这事情不简单,就回了句:您好,我是小胖&…

注意String.Split的几个重载形式
String.Split应该是经常用到的一个函数了,经常的有下面两种形式 public string[] Split(char[] separator, StringSplitOptions options); public string[] Split(string[] separator, StringSplitOptions options); 1. 多数情况下我们会使用第一种,代码里可能这…

如何让猎头找到你
如何让猎头找到你

libev源码解析——总览
libev是个非常优秀的基于事件的循环库,很多开源软件,比如nodejs就是使用其实现基础功能。本系列将对该库进行源码分析。(转载请指明出于breaksoftware的csdn博客) 不知道是被墙了还是网站不再维护,它的官网(…
GPT-2仅是“反刍”知识,真正理解语言还要改弦更张
作者 | Gary Marcus译者 | 泓技编辑 | 夕颜出品 | AI科技大本营(ID:rgznai100)【导读】OpenAI的GPT-2正被广泛地讨论,无论是《纽约客》还是《经济学人》,我们都能看到有关它的话题。关于自然和人工智能,它想…

sap business one 笑谈
Sap Business .e 出生在以色列,生下来的时候父母给起了个小名叫SBO,据说他的亲生父母是SAP家庭里的一个重要成员,后来SAP家族里的长老认为SBO长得不错,挺好看的。毕竟SAP家族里生下来的儿子都是胖胖的,想要个瘦点长相好…

来51学院的第一天
【来51学院的第一天】转载于:https://blog.51cto.com/10801189/1703279
libev源码解析——监视器(watcher)结构和组织形式
在《libev源码解析——总览》中,我们介绍了libev的一些重要变量在不同编译参数下的定义位置。由于这些变量在多线程下没有同步问题,所以我们将问题简化,所提到的变量都是线程内部独有的,不用考虑任何多线程问题。(转载…

《评人工智能如何走向新阶段》后记(再续16)
由AI科技大本营下载自视觉中国181.5种常见的机器学习方法。 (1)线性回归linear regression: 一种流行的回归算法,从样本特征的线性组合,linear combination中学习模型。 (2)负数几率回归,logis…

怎么样才能快速的把淘宝店铺推广出去
我来到淘宝近一个月了,目前顺利地得到了两颗心心.感触颇多.其中店铺的推广显得尤其重要,应很多淘友的提问,我把一些店铺推广技巧介绍如下,你如果觉得有益,就回一下贴,以示支持.在这里先谢谢了!先看第一板斧:一、修练内功ÿ…