博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于Webpy实现服务器策略模型
阅读量:5962 次
发布时间:2019-06-19

本文共 3570 字,大约阅读时间需要 11 分钟。

现在我们来谈一些(黑)科技,希望能给大家一些启发和帮助。现在我有一个策略文件addition.policy

load!: addition_delegate.pyawait: first_string -> s1apply: concat_with_time(s1) -> s1await: second_string -> s2apply: concat_with_time(s2) -> s2await: return_resultapply: join_with_linefeed(s1, s2) -> resultyield: result

还有一个委托函数的Python源码addition_delegate.py

# addition_delegate.pydef concat_with_time(s):    import time    return str(s) + time.ctime()def join_with_linefeed(s1, s2):    return "%s\n%s\n" % (str(s1), str(s2))

这是什么语法?但是我们大抵都能明白它想干什么:先后获取两个字符串,分别将它们和时间拼接在一起,然后在获取return_result后回传结果。然后呢?然后我们有一些Web接口,简单地用web.py编写main.py

#!/usr/bin/env pythonimport webfrom policy import resumeclass first_str_view:    def GET(self):        resume("addition.policy", "first_str",            value = web.input()["value"], anew = True)        return ""class second_str_view:    def GET(self):        resume("addition.policy", "second_str",            value = web.input()["value"])        return ""class return_result_view:    def GET(self):        return resume("addition.policy", "return_result")urls = [    '/first_str/?', first_str_view,    '/second_str/?', second_str_view,    '/return_result/?', return_result_view,]if __name__ == "__main__":    app = web.application(urls, globals())    app.run()

就算没用过web.py的人都大抵能明白这个结构是什么意思了,除了那个resume有点不知所谓之外,但是结合上面的那个addition.policy,好像看上去也挺合理,大概就是从acquire处断开,然后得到输入后继续执行那个policy。如你所料:

$ ./main.py 9999 &[1] 19121http://0.0.0.0:9999/$ curl "http://localhost:9999/first_str?value=First+Record+"$ curl "http://localhost:9999/second_str?value=Second+Record+"$ curl "http://localhost:9999/return_result"First Record Sat Sep  5 15:59:25 2015Second Record Sat Sep  5 15:59:28 2015

这样可以解决很多问题。比如在用户更变邮箱的时候,用户先提交新邮箱,然后还要等等他什么时候去邮箱里收验证邮件,这样更变邮箱的操作才完成。还有一些更麻烦的操作,整个流程下来,要收几次输入,然后才能真正地输入成功存进数据库。举个例子,你可以简单地写一个策略文件,让它控制整个流程,接口只需要跟用户打交道就好了:

load!: email_serviceassert!: is_authenticatedawait: modify_email -> addressapply: send_verf_email(address)await: verf_email_recvapply: save_current_user_info(address)

不得不说这种模型有点像是协程(coroutine),但是不是用它来实现的,毕竟:一次请求完成了整个线程大大小小都结束了哪里还有协程啊对吧。这也不是WebSocket能解决的:比如收验证邮件,都在第二个地方连接了,哪里还有Socket可言。这里针对的情况是,两次连接之间的时间段是断开的情况。(如果非要用设计模式来说,我觉得是一个策略+状态+解释器的组合,然而我并不喜欢被设计模式拘束)

实现思路

主要是在模拟恢复执行的时候能较好地恢复原有上下文,在Python有exec的情况下,想办法生成可配合执行Python代码是一个不错的选择。恢复执行有这些步骤:

  • 解析策略文件

  • 从持久存储设备中反序列化上下文

  • 找到断点应该在哪里,按照这个位置,执行一些每次都要执行的语句(标 !号)

  • 一直执行到下一个await点,退出执行

先看一下resume()函数的一个实现是什么样子的:

from policy import policyimport pickleimport osdef resume(pf, await_tag, value = None, anew = False):    c = context.start_new() if anew else \        pickle.load(file("context.dump", "rb"))    p = policy.load(pf)    p.load_context(c)    p.provide(await_tag, value)    ret = None        try:        ret = p.resume()    finally:        os.remove("context.dump")    if p.is_end():        os.remove("context.dump")    return ret

这里的contextpolicy是我对这个模型的一个实现,可以看出这两者是分开保存的,Policy几乎就是一个常量了,硬编码在一个文件里。而Context在每一次退出执行的时候都要保存一下,除非已经执行结束了,或者执行出现了错误(也相当于执行结束),才把它削除。

Policy-Control已经推上了Github,代码很短,欢迎各位围观:

附:语法清单

digit  := '0' | ... | '9'underscore := '_'symbol ::=    letter | underscore    { letter | underscore | digit }command ::= symbolvariable ::= symbolstring ::=    '"' {    [ 0x00 | ... | 0x21 | 0x23 | ... | 0x7f | '\n' | '\r' | '\"' | '\\' ]    } '"'value ::= string | variableparameter ::= valueparameter-list ::=    '('    [ parameter-list ',' parameter | parameter ]    ')'argument ::= symbol [ parameter-list ]argument-list ::= argument-list argument | argumentcommand-line ::=    command [ '!' ] ':'    argument-list    [ '->' variable ]policy ::=    policy \n command-line | command-line

转载地址:http://kznax.baihongyu.com/

你可能感兴趣的文章
QQ把游戏放进聊天框,这一点Facebook和微信都没做到
查看>>
在线匿名之父意欲终结“加密战争”
查看>>
WLAN市场销量逐步逼近有线网络
查看>>
力龙信息布局大数据领域
查看>>
大数据巧治职业差评师 生存空间锐减九成
查看>>
天津开展免费无线局域网建设
查看>>
提高信息安全意识对网络勒索病毒说不
查看>>
英国政府可能利用曼彻斯特自杀袭击要求互联网公司破解加密
查看>>
Mozilla 将大幅简化火狐浏览器的同步操作
查看>>
Convert Url to InetAddress
查看>>
oracle 限制特定ip登录
查看>>
解酒方法
查看>>
vi 命令
查看>>
1.1
查看>>
[logstash-input-redis]插件使用详解
查看>>
优化应用的电池寿命(笔记)-1
查看>>
SSH Secure Shell Client
查看>>
JFinal源码分析------初始化那些事儿
查看>>
处理 允许远程协助连接这台计算机 灰色
查看>>
使用Jquery 加载页面时调用JS
查看>>