APScheduler 源码阅读笔记

概述

APScheduler 是由 python 实现的一个轻量级任务调度器,它可以按照一定间隔(IntervalTrigger)、指定时间(2.1中的SimpleTrigger/3.0中的DateTrigger)或者以类似 cron(CronTrigger) 的形式触发待执行任务(即调用函数或者调用 python 的 callable 对象)。现在 pypi 上的稳定版是 APScheduler 2.1.1,3.0 版本在 class Scheduler 中移除了针对不同 trigger 的 add_trigger_job() 接口,统一为 add_job(),但是底层实现变化不大。我主要看了 2.1.1 的代码。代码很简洁,加起来一共2049行。

模块组织

  • Scheduler 调度器的核心部分,负责对 job 的管理和调度,用户使用添加/移除任务,启动调度器都通过 Scheduler 提供的接口完成。

  • Job 封装了需要调度的任务,每一个 Job 实例是在 Scheduler 添加 job 时被初始化,具体的初始化参数决定了调度被触发的形式(3类不同的trigger)。

  • Trigger 包含 SimpleTrigger,IntervalTrigger和 CronTrigger 三个类。Trigger 的作用就是计算下一次触发任务的时间。

  • JobStore 抽象基类,针对任务存储的介质有多个实现,包括基于内存(RAMJobStore)、使用shelve的简单持久化存储(ShelveJobStore)、使用数据库存储(RedisJobStore,MongoDBJobStore)等。如果不指定参数默认使用 RAMJobStore,使用持久化的 JobStore 的目的是在 Scheduler 重启之后能够恢复原有的任务调度。

底层实现

从分析 Scheduler 类入手,首先看项目中自带的example:

Read on →

使用Tornado进行异步编程

翻译自:Asynchronous programming with Tornado

对于初学者来说异步编程很令人迷惑,因此我觉得有必要介绍一些有用的基本概念来帮助初学者避免一些常见的陷阱。如果希望理解通用的异步编程模型,可以查看以下这些网络资源,Introduction to Asynchronous ProgrammingTwisted Introduction。在这篇文章中我将会着眼于如何使用 Tornado 进行异步编程。

来自Tornado主页的一段话:

FriendFeed’s web server is a relatively simple, non-blocking web server written in Python. The FriendFeed application is written using a web framework that looks a bit like web.py or Google’s webapp, but with additional tools and optimizations to take advantage of the non-blocking web server and tools. Tornado is an open source version of this web server and some of the tools we use most often at FriendFeed. The framework is distinct from most mainstream web server frameworks (and certainly most Python frameworks) because it is non-blocking and reasonably fast. Because it is non-blocking and uses epoll or kqueue, it can handle thousands of simultaneous standing connections, which means the framework is ideal for real-time web services. We built the web server specifically to handle FriendFeed’s real-time features every active user of FriendFeed maintains an open connection to the FriendFeed servers. (For more information on scaling servers to support thousands of clients, see The C10K problem.)

对于初学者首先需要认清的是自己是否真的需要异步操作。异步编程比同步编程复杂得多,因此有人说:异步编程是不适合人类大脑的。

Read on →

Stl Make_heap在llvm和g++下的不同实现

先来看一段十分简单的使用stl的c++代码,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <vector>
using namespace std;

int main(void) {
    vector<int> vec;
    int len = 5;
    for (int i = 1; i <= len; ++i)
        vec.push_back(i);
    make_heap(vec.begin(), vec.end());
    for (vector<int>::iterator iter = vec.begin(); iter != vec.end(); iter++) {
        cout << *iter << " ";
    }
    cout << endl;
    return 0;
}

发现在 xcode 中运行和在 mac terminal 中利用 g++ 编译运行结果不一样,分别为:

1
2
xcode-default : 5 4 2 1 3
terminal-g++  : 5 4 3 1 2
Read on →
C++, STL

Tornado源码分析5

Tornado的web框架在web.py中实现,主要包括RequestHandler类(本质为对http请求处理的封装)和Application类(是一些列请求处理的集合,构成的一个web-application,源代码注释不翻译更容易理解:A collection of request handlers that make up a web application)。

RequestHandler分析

RequestHandler提供了一个针对http请求处理的基类封装,方法比较多,主要有以下功能:

  1. 提供了GET/HEAD/POST/DELETE/PATCH/PUT/OPTIONS等方法的功能接口,具体开发时RequestHandler的子类重写这些方法以支持不同需求的请求处理。

  2. 提供对http请求的处理方法,包括对headers,页面元素,cookie的处理。

  3. 提供对请求响应的一些列功能,包括redirect,write(将数据写入输出缓冲区),渲染模板(render, reander_string)等

  4. 其他的一些辅助功能,如结束请求/响应,刷新输出缓冲区,对用户授权相关处理等。

Read on →

Android运行脚本与定时工具

用惯了crontab,实验室的机器因为某些原因连不上,于是希望在自己的Android手机上完成定时执行一些脚本的任务。google一下找到了 android应用实现定时打电话 这样一篇文章,正好满足我的需求。下面做一个简单的总结。

安装的软件

  • SL4A(Scripting Layer for Android),Andriod系统下运行脚本的环境,可以在终端、后台或Locale中运行,现阶段支持Python, Perl, JRuby, Lua, BeanShell, JavaScript, Tcl和shell脚本。

  • Py4A,SL4A的python插件,安装之后就可以运行python脚本。

  • TaskBomb task scheduler,一个可以执行计划任务的app,类似于Unix中的crontab。

  • SL4A Script Launcher,TaskBomb可以通过此app执行SL4A脚本。

Read on →

Tornado源码分析4

IOStream对socket读写进行了封装,分别提供读、写缓冲区实现对socket的异步读写。当socket被accept之后HTTPServer的_handle_connection会被回调并初始化IOStream对象,进一步通过IOStream提供的功能接口完成socket的读写。文章接下来将关注IOStream实现读写的细节。

IOStream的初始化

IOStream初始化过程中主要完成以下操作:

  1. 绑定对应的socket
  2. 绑定ioloop
  3. 创建读缓冲区_read_buffer,一个python deque容器
  4. 创建写缓冲区_write_buffer,同样也是一个python deque容器
Read on →