Serverless實踐系列(三):突破傳統OJ瓶頸,“判題姬”接入雲函數

隨着時代的發展,OJ已經真正成爲測評工具,其作用不再侷限爲ACM備戰,還有老師檢測學生能力、學生入學考試、能力評測(例如ZJU的PAT)、找工作刷題和麪試(例如牛客)等,而目前OJ的開源框架也越來越多,但是很多OJ都是基於HUSTOJ進行定製或者二次開發。

無論是什麼方法,在OJ的衆多問題中,有一個就是:性能問題。說實話,我在一些OJ羣裏,經常會看到有人問:1核1G的機器,可以同時判多少題目?可以有多少人同時用?如果比賽,大約有多少人需要多高性能的機器?那麼"判題姬"是否只能存在傳統的宿主機中,能否通過其他方式煥發新的生命力?

有一種方法,就是和現有的雲函數進行結合。

簡單思路

通過雲函數實現在線編程的思路基本有兩個:

  • 每個用戶的代碼建立一個函數,用後刪除;
  • 每個語言建立一個函數,用戶傳遞代碼,每次執行;

這兩種方法,第一種無疑是簡單的,但是目前對於很多雲函數服務商來說,函數數量有一定限制,而且每次執行這個操作相對比較繁瑣。

所以,本文采用第二種策略,建立一個函數,每次執行,用戶傳入代碼,系統執行,返回結果。

基本實現

代碼寫入系統:

def WriteCode(code):
    try:
        with open("/tmp/mytest.py", "w") as f:
            f.write(code)
        return True
    except Exception as e:
        print(e)
        return False

執行代碼:

def RunCode(input_data=None):
    child = subprocess.Popen("python /tmp/mytest.py", stdin=input_data, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, shell=True)
    error = child.stderr.read()
    output = child.stdout.read()
    return error, output

代碼和用例處理邏輯:

def main_handler(event, context):
    if WriteCode(event["code"]):
        try:
            temp_list = []
            for eve in event["input"]:
                result = RunCode()
                temp_list.append({"error":result[0].decode("utf-8"),"result": result[1].decode("utf-8"), "exception":""})
            return json.dumps(temp_list)
        except Exception as e:
            return json.dumps({"error":"","result": "", "exception":str(e)})

用戶在傳入數據的時候,需要注意事件爲:

{
  "code": "print('hello')",
  "input": ["111","22222"]
}

這樣就可以在每次請求的時候把代碼傳入(code),每個測試用例的input就是input內容。
本題輸出結果:

此時,就實現了Python判題機的基本功能,此時通過騰訊云云API:
https://cloud.tencent.com/document/api/583/17243)實現參數傳入,通過
Explorer(https://console.cloud.tencent.com/api/explorer?Product=scf&Version=2018-04-16&Action=Invoke&SignVersion=
進行代碼撰寫,直接接入自己的OJ就可以了。

One More Thing

雖然這是一個簡單的代碼執行工具,但是實際上這個小工具可以在很多地方有着額外的應用。本文我只是再次只是拋磚引玉,例如我們做了一個OJ,如果在本地跑代碼可能性能和安全性都會受到挑戰,那麼此時,放入騰訊云云函數中,就會簡單、安全、便捷的多,最主要的是騰訊雲的函數調用免費額度很高。

此外,如果臨時舉辦比賽,也不用費心費力擴容縮容,只要有雲函數,後端的主要壓力,都傳給Serverless搞定,這也算是發揮了雲函數的一個優勢和特性。

那麼,除了在OJ中使用的用途,它還有啥用?簡單舉兩個例子:

  • Anycodes、Codepad這些在線編程網站,之前很多人就問是如何實現的,試想一下,通過這個策略,是不是很好實現了在線編程?確切說,只需要一個前端,就可以實現在線寫代碼的一個網頁。
  • 菜鳥教程這些網站,可以看代碼然後點擊運行,很炫酷的功能,很多小夥伴也想往自己博客增加一個類似的功能,也可以基於這個方法來實現。

作者介紹:

劉宇,騰訊雲Serverless團隊後臺研發工程師。畢業於浙江大學,先後參與騰訊云云函數產品研發、自動擴縮容、CLI等模塊建設以及社區相關工作。本文轉載自微信公衆號 ServerlessCloudNative(ID:ServerlessGo)

《Serverless 實踐系列(一):如何通過 SCF 與自然語言處理爲網站賦能》
《Serverless 實踐系列(二):爲 Python 雲函數打包依賴》
《Serverless 實踐系列(四):網站監控腳本的實現》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章