在一个容器中托管简单的Python脚本来处理并发,配置,缓存等

问题描述:

我的第一个真实世界的Python项目是编写一个简单的框架(或重用/改编现有的框架),它可以包装小python脚本其使用的“容器”来处理样板任务,如收集的监控工具自定义数据):在一个容器中托管简单的Python脚本来处理并发,配置,缓存等

  • 从文件中读取脚本的配置(并保持这些信息是最新的,如果该文件的更改和处理解密敏感配置数据)
  • 在不同线程中运行同一脚本的多个实例,而不是为每个线程启动一个新进程
  • 暴露的API来缓存昂贵的数据和存储从一个脚本调用持久状态下一

今天,脚本作者必须处理上述问题,这通常意味着大多数脚本编写者不能够正确处理它们,导致错误和性能问题。除了避免错误之外,我们还需要一个解决方案来降低创建和维护脚本的工作量,尤其是考虑到许多脚本作者可能不是经过培训的程序员。

下面是我一直在想的API的示例,以及我希望得到您的反馈意见的示例。

脚本编写者需要构建一个方法,它需要(作为输入)脚本需要完成其工作的配置,并且返回一个python对象或调用一个方法来以大块的形式回传数据。可选地,脚本编写者可以提供处理启动和/或关闭任务的方法。

HTTP取脚本示例(在伪代码,忽略实际的数据撷取细节专注于容器的API):

def run (config, context, cache) : 
    results = http_library_call (config.url, config.http_method, config.username, config.password, ...) 
    return { html : results.html, status_code : results.status, headers : results.response_headers } 

def init(config, context, cache) : 
    config.max_threads = 20 # up to 20 URLs at one time (per process) 
    config.max_processes = 3 # launch up to 3 concurrent processes 
    config.keepalive = 1200 # keep process alive for 10 mins without another call 
    config.process_recycle.requests = 1000 # restart the process every 1000 requests (to avoid leaks) 
    config.kill_timeout = 600 # kill the process if any call lasts longer than 10 minutes 

数据库数据获取脚本示例可能是这样的(在伪代码):

def run (config, context, cache) : 
    expensive = context.cache["something_expensive"] 
    for record in db_library_call (expensive, context.checkpoint, config.connection_string) : 
     context.log (record, "logDate") # log all properties, optionally specify name of timestamp property 
     last_date = record["logDate"] 
    context.checkpoint = last_date # persistent checkpoint, used next time through 

def init(config, context, cache) : 
    cache["something_expensive"] = get_expensive_thing() 

def shutdown(config, context, cache) : 
    expensive = cache["something_expensive"] 
    expensive.release_me() 

这是API适当“Python化”,还是有事情我应该做的,使这个更自然的Python的编剧? (我更熟悉大厦C++/C#/的Java API,所以我怀疑我错过有用的Python的成语。)

具体的问题:

  • 是很自然传递一个“配置”对象成一种方法并要求被调用者设置各种配置选项?还是有另一种喜欢的方式来做到这一点?
  • 当一个被调用者需要将数据流传回给调用者时,是否类似于context.log()(请参见上文)的方法,还是应该使用yield? (yeild似乎很自然,但我担心它会超过大多数脚本编写者的头)
  • 我的方法要求脚本使用预定义名称(例如“run”,“init”,“shutdown”)定义函数。这是做这件事的好方法吗?如果不是,还有什么其他机制会更自然?
  • 我将相同的config, context, cache参数传递给每个方法。使用单个“上下文”参数会更好吗?用全局变量代替它会更好吗?
  • 最后,是否有建议使这种简单的“脚本运行容器”易于编写的现有库?

看看用于处理python数据库内容的SQL Alchemy。另外为了使脚本编写更容易处理并发查看Stackless Python。