基于Webpy實現服務器策略模型

jopen 9年前發布 | 8K 次閱讀 webpy

現在我們來談一些(黑)科技,希望能給大家一些啟發和幫助。現在我有一個策略文件addition.policy:

acquire: first_str -> a
apply: concat_with_time(a) -> a
acquire: first_str -> b
apply: concat_with_time(b) -> b

await: return_result apply: join_line(a, b) -> result yield: result</pre>

還有一個委托函數的Python源碼addition.delegate.py:

# addition.delegate.py

import time

def concat_with_time(s): return s + time.ctime()

def join_line(s1, s2): return s1 + "\n" + s2 + "\n"</pre>

這是什么語法?但是我們大抵都能明白它想干什么:先后獲取兩個字符串,分別將它們和時間拼接在一起,然后在獲取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", "first_str", value = web.input()["value"])
        return ""
class second_str_view:
    def GET(self):
        resume("addition", "second_str", value = web.input()["value"])
        return ""
class return_result_view:
    def GET(self):
        return resume("addition", "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

這樣可以解決很多問題。比如在用戶更變郵箱的時候,用戶先提交新郵箱,然后還要等等他什么時候去郵箱里收驗證郵件,這樣更變郵箱的操作才完成。還有一些更麻煩的操作,整個流程下來,要收幾次輸入,然后才能真正地輸入成功存進數據庫。舉個例子,你可以簡單地寫一個策略文件,讓它控制整個流程,接口只需要跟用戶打交道就好了:

assert: is_authenticated()
acquire: modify_email -> address
execute: send_verification_mail(address)
await: email_verified
execute: save_user_info("email", address)

不得不說這種模型有點像是協程(coroutine),但是不是用它來實現的,畢竟:一次請求完成了整個線程大大小小都結束了哪里還有協程啊對吧。這也不是WebSocket能解決的:比如收驗證郵件,都在第二個地方連接了,哪里還有Socket可言。這里針對的情況是,兩次連接之間的時間段是 斷開 的情況。

實現思路

主要是在模擬恢復執行的時候能較好地恢復原有上下文,在Python有exec的情況下,想辦法生成可配合執行Python代碼是一個不錯的選擇。恢復執行有這些步驟:

  • 解析策略文件

    </li>

  • 從持久存儲設備中反序列化變量

    </li>

  • 找到斷點應該在哪里,按照這個位置:

    • 載入模塊(如上面的time)

      </li>

    • 載入上下文變量(如上面的a,b)

      </li> </ul> </li>

    • 一直執行到下一個await點,退出執行

      </li> </ul>

      /* 具體的實現明天看有沒有時間再更 */

      附: 語法清單

      digit  := '0' | ... | '9'
      underscore := '_'
      symbol ::=
          letter | underscore
          { letter | underscore | digit }
      command ::= symbol
      variable ::= symbol
      string ::=
          '"' {
          [ 0x00 | ... | 0x21 | 0x23 | ... | 0x7f | '\n' | '\r' | '\"' | '\\' ]
          } '"'
      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 \n command-line | command-line
      原文 http://segmentfault.com/a/1190000003708486

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!