摘要:現在我們來談一些黑科技,希望能給大家一些啟發和幫助。這里針對的情況是,兩次連接之間的時間段是斷開的情況。而在每一次退出執行的時候都要保存一下,除非已經執行結束了,或者執行出現了錯誤也相當于執行結束,才把它削除。
現在我們來談一些(黑)科技,希望能給大家一些啟發和幫助。現在我有一個策略文件addition.policy:
load!: addition_delegate.py await: first_string -> s1 apply: concat_with_time(s1) -> s1 await: second_string -> s2 apply: concat_with_time(s2) -> s2 await: return_result apply: join_with_linefeed(s1, s2) -> result yield: result
還有一個委托函數的Python源碼addition_delegate.py:
# addition_delegate.py def concat_with_time(s): import time return str(s) + time.ctime() def join_with_linefeed(s1, s2): return "%s %s " % (str(s1), str(s2))
這是什么語法?但是我們大抵都能明白它想干什么:先后獲取兩個字符串,分別將它們和時間拼接在一起,然后在獲取return_result后回傳結果。然后呢?然后我們有一些Web接口,簡單地用web.py編寫main.py:
#!/usr/bin/env python import web from policy import resume class 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] 19121 http://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 2015 Second Record Sat Sep 5 15:59:28 2015
這樣可以解決很多問題。比如在用戶更變郵箱的時候,用戶先提交新郵箱,然后還要等等他什么時候去郵箱里收驗證郵件,這樣更變郵箱的操作才完成。還有一些更麻煩的操作,整個流程下來,要收幾次輸入,然后才能真正地輸入成功存進數據庫。舉個例子,你可以簡單地寫一個策略文件,讓它控制整個流程,接口只需要跟用戶打交道就好了:
load!: email_service assert!: is_authenticated await: modify_email -> address apply: send_verf_email(address) await: verf_email_recv apply: save_current_user_info(address)
不得不說這種模型有點像是協程(coroutine),但是不是用它來實現的,畢竟:一次請求完成了整個線程大大小小都結束了哪里還有協程啊對吧。這也不是WebSocket能解決的:比如收驗證郵件,都在第二個地方連接了,哪里還有Socket可言。這里針對的情況是,兩次連接之間的時間段是斷開的情況。(如果非要用設計模式來說,我覺得是一個策略+狀態+解釋器的組合,然而我并不喜歡被設計模式拘束)
實現思路主要是在模擬恢復執行的時候能較好地恢復原有上下文,在Python有exec的情況下,想辦法生成可配合執行Python代碼是一個不錯的選擇。恢復執行有這些步驟:
解析策略文件
從持久存儲設備中反序列化上下文
找到斷點應該在哪里,按照這個位置,執行一些每次都要執行的語句(標 !號)
一直執行到下一個await點,退出執行
先看一下resume()函數的一個實現是什么樣子的:
from policy import policy import pickle import os def 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
這里的context和policy是我對這個模型的一個實現,可以看出這兩者是分開保存的,Policy幾乎就是一個常量了,硬編碼在一個文件里。而Context在每一次退出執行的時候都要保存一下,除非已經執行結束了,或者執行出現了錯誤(也相當于執行結束),才把它削除。
Policy-Control已經推上了Github,代碼很短,歡迎各位圍觀:https://github.com/Shihira/policy-control
附:語法清單
digit := "0" | ... | "9" underscore := "_" symbol ::= letter | underscore { letter | underscore | digit } command ::= symbol variable ::= symbol string ::= """ { [ 0x00 | ... | 0x21 | 0x23 | ... | 0x7f | " " | " " | """ | "" ] } """ value ::= string | variable parameter ::= value parameter-list ::= "(" [ parameter-list "," parameter | parameter ] ")" argument ::= symbol [ parameter-list ] argument-list ::= argument-list argument | argument command-line ::= command [ "!" ] ":" argument-list [ "->" variable ] policy ::= policy command-line | command-line
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/37602.html
摘要:前言在文章基于環境搭建框架方法介紹中介紹了客戶端和服務器的交互過程,服務器接收客戶端的請求后,由應用服務器對瀏覽器的請求進行處理,將生成的響應傳遞給服務器,再由服務器返回給客戶端。 前言 在文章《基于Linux環境搭建Nginx+uWSGI+Python框架方法介紹》中介紹了客戶端和Web服務器的交互過程,Web服務器接收客戶端的請求后,由Web應用服務器對瀏覽器的請求進行處理,將生成...
摘要:軟件開發者通常依據特定的框架實現更為復雜的商業運用和業務邏輯。所有,做開發,要用一個框架。的性能是相當優異的,因為它師徒解決一個被稱之為問題,就是處理大于或等于一萬的并發。 One does not live by bread alone,but by every word that comes from the mouth of God --(MATTHEW4:4) 不...
摘要:描述實現生成的業務接口產生一系列問題在部署的過程中遇到問題問題引用包在中創建應用的過程中默認是支出的,無需安裝。 描述 SAE(SinaAppEngine) + webpy + qiniu sdk 實現生成token的業務接口 產生一系列問題 在部署的過程中遇到問題 問題1 引用qiniu for python 包 在SAE 中創建python web應用的過程中默認是支出webpy ...
閱讀 3667·2021-10-11 11:09
閱讀 1337·2021-09-24 10:35
閱讀 3423·2021-07-29 13:48
閱讀 460·2019-08-30 13:15
閱讀 2511·2019-08-30 12:53
閱讀 3183·2019-08-30 12:44
閱讀 2712·2019-08-29 16:57
閱讀 957·2019-08-29 12:26