已針對 Hex v2.0 發布新版解決程序

· 作者:Eric Meadows-Jönsson

Hex 2.0 不再支援 Elixir 1.0-1.4。Hex 1.0 將繼續維護,但只會收到安全性更新。更多詳情請參閱 Hex 1.0 的發行公告

新版解決程序

2.0 版中最大的變更,是導入新版解決程序 hex_solver。套件管理員的版解決程序必須有能力找出合理數量的一組相容套件的最新版本,而且不能違反各套件使用者指定的版本需求,並在合理的時間內完成,如果版本解決失敗,還必須顯示清楚的訊息,說明失敗的原因。

當 2014 年初開始研發 Hex 時,現有的解決程序演算即已存在。自從最初導入之後,已做了許多改良,例如效能改良和改善的錯誤訊息,但底層演算基本上沒有改變。最近出現的狀況是,解決程序似乎會凍結(實際上並未凍結,只是花很長時間才找出解法),隨著 Elixir 專案的依賴項複雜度和數量增加,加上 Hex 登錄變得越來越大,這個問題也變得越來越普遍。

版本解決可概化為 布林可滿足性問題,因此時間複雜度是 NP-complete,這表示沒有已知演算法可以在較大輸入集時快速解決此問題。存在 SAT 求解器 仍能在合理的時間內為許多輸入求解。SAT 求解器的問題在於它們是概化的,不能針對版本解決的特定問題領域使用任何最佳化,另一個問題是通常有許多解決方案符合版本需求,但我們希望套件管理員始終是最新相容版本。最後,SAT 求解器無法建立解釋性錯誤訊息,來說明求解為何失敗。

考量到這些問題,我們選擇將新的求解器建立在 Natalie Weizenbaum 的 PubGrub 上,而 PubGrub 又是建立在 衝突驅動子句學習 上的。PubGrub 用於稱為 pub 的 Dart 程式語言套件管理員 中。

傳統版本求解器遇到衝突版本時,會簡單回溯到可能引入衝突版本的套件所在位置,然後嘗試不同的版本。這種方法的問題在於,很難推論出衝突的根本原因,而且即使已知不相容,卻經常嘗試同一組套件版本。PubGrub 藉由記錄衝突的根源來解決這個問題,然後即可略過導致衝突的所有套件版本組合,並避免搜尋範圍的廣大區域。記錄衝突原因還有一個好處,就是我們可以用它們來建置人類可讀的錯誤訊息,如果找不到解決方案,會逐步說明求解失敗的原因。

solve failure

下一步是什麼?

我們計畫用 Mint 取代 Hex 中目前使用 httpc 的 HTTP 用戶端。Mint 支援 HTTP/2,因此可能會看到一些效能提升,但最重要的是,使用 Mint 時,我們可以更精確地控制要求逾時。使用 httpc 時,只能對整個要求設定逾時,但使用 Mint 時,逾時可根據最後接收到的資料設定,這可以讓使用者在網速慢或不穩定的網路中取得更大的簡便性。

具備初始支援 Oktta 及 Google 的 SSO 登入也在我們計畫的一環。我們會同時幫 CLI 加入網路驗證功能,以支援 SSO 和 2FA。

如果你有興趣參與這些功能,或是有其他改進想法,可以到 Elixir slack 的 #hex 頻道找到 Hex 團隊,或是在 github.com/hexpm/hexpmgithub.com/hexpm/hex 的 GitHub 上找到我們。