GitHub推出Scientist,幫助開發者重構關鍵路徑代碼
GitHub最近正式發布了 Scientist 1.0,這是一個能夠幫助開發者更有信心地重構或重寫代碼的Ruby庫, 作者 是GitHub的工程師Jesse Toth。在過去幾年中,Scientist已經為GitHub上的大量項目所用。
按照Toth的看法,Scientist對于關鍵代碼的重構尤為實用,在進行這種重構時,開發者對于新的實現的正確性要具備很強的信心。在此之前,一種常見的重構方法是采取 BranchByAbstraction 架構模式,這種模式本身雖然非常實用,但它只是保證了新的組件能夠取代舊組件所出現的每一個場合而已。而Scientist的目標是提供更好的正確性保障。此外,Scientist還將嘗試繞開測試過程的限制,因為測試過程往往無法做到涵蓋所有可能的情況或輸入數據的組合。
Scientist的基本思想是建立一種受控試驗(experiment),在其中同時運行舊的代碼路徑與新的代碼路徑,隨后對兩者的輸出進行比較,并對任何不匹配或異常進行記錄。舊的代碼路徑將保證整個系統在重構的實驗階段仍能夠正確地運行,而新的代碼路徑的正確性也同時得到了驗證。
一個experiment是一種輕量級的抽象,它包含了兩種行為。use行為表示執行舊的代碼路徑,而try行為則表示執行新的代碼路徑。
experiment = Scientist::Default.new "my-experiment"
experiment.use { <call the old code here, the control> }
experiment.try { <call the new code here, the candidate> }
experiment.run
#...
def publish(result)
#...
run方法將始終返回與use代碼塊相同的返回結果,而publish方法將在experiment的末尾進行調用,以發布所收集到的數據。除了對try與use代碼塊的結果進行比較之外,Scientist還會隨機地調整他們的執行順序,以回避兩者之間可能產生的相互關聯,它還將評估兩種方法的執行時間、管理異常、并發布所收集到結果。
Scientist提供了大量的方法對它的默認行為進行自定義,舉例來說,用戶可以定義一個特定的比較方法,以覆蓋默認的 == 操作符,這一方法將用于輸出的對照比較。此外,用戶還可以提供一個上下文對象,可在發布數據時使用。用戶還可以控制啟動任務、啟動或關閉experiment的執行等等。Scientist還提供了一些更高級的控制選項,以允許用戶忽略結果、運行多個try代碼塊、或只運行try代碼塊,以涵蓋某些特殊的用例。
InfoQ與GitHub的首席工程師Jesse Toth進行了一次對話。
能否請你描述一下Scientist的誕生過程?
Scientist的誕生過程是這樣的。當時我有一位前同事Rick Bradley正在嘗試重構一個非常復雜的API終結點,該API將返回一個長長的repository列表。他不確信所改動的代碼是否已經得到了足夠的測試覆蓋,并希望通過某種方式對真實的數據集進行測試。于是他快速地修改了一部分代碼以調用重構后的方法,并且每當重構后的方法與原始方法產生不一致行為的時候,就在我們的指標棧中將數據記錄下來。這種方法相當有效,于是我們為它編寫了一個庫,讓任何人都可以利用它進行相同的實驗。
為了讓現有的代碼能夠通過Scientist進行一系列實驗,所改動的代碼會產生多大的開銷?你在GitHub中又是怎樣在使用Scientist時調整它的投入與產出比的呢?
這取決于你希望進行實驗的那部分代碼有多大開銷,以及這部分代碼的調用頻率。如果候選的重構代碼與對照的原始代碼具有完全相同的效率,那么運行一個experiment就是2倍的開銷。如果候選代碼極大地提升了性能,那么開銷就會大大地降低。
如果我們認為運行Scientist experiment的代價很高,那么我們就會緩慢地提高運行experiment的請求的比例。如果experiment的執行能夠涵蓋1%或5%的訪問量,這就已足夠為我們收集大量的性能與不匹配方面的數據了。
你是否希望在Scientist中引入更多的特性?
Scientist已經具備了我們目前所需的所有特性,當然,如果有用戶發現了某種使用Scientist的其他方式,并希望為支持這一方式而添加相應的特性,我們將非常樂于看到這方面的貢獻。
Scientist所需的運行環境是已安裝了Ruby 1.9的Unix系統,可以從對應的 gem 中進行安裝。
查看英文原文: GitHub's Scientist Aims to Help Refactoring Critical Paths
來自: http://www.infoq.com/cn/news/2016/02/github-scientist-refactoring