#依賴和雨傘項目git
本章,咱們將討論如何在Mix中管理依賴.github
咱們的kv
應用已經完成,因此是時候實現可以處理咱們在第一章中定義的請求的服務器了:服務器
CREATE shopping OK PUT shopping milk 1 OK PUT shopping eggs 3 OK GET shopping milk 1 OK DELETE shopping eggs OK
然而,咱們將構建一個最爲另外一個應用的TCP服務器,它是kv
應用的一個客戶端.而不是添加更多代碼到kv
應用中.由於對於應用來講,整個運行時和Elixir生態系統都是它的齒輪,因此咱們可以把咱們的項目分解成多個更小的項目,而不是組建一個巨大的,整個的應用.app
在建立應用以前,咱們必須討論Mix是如何處理依賴的.在實際中,有兩種咱們常見的依賴:內部和外部依賴.Mix支持這兩種機制.分佈式
#外部依賴函數
外部依賴就是你的業務範圍以外的東西.例如,若是你須要一個HTTP API給你的分佈式KV應用,你可使用Plug項目做爲一個外部依賴.工具
安裝外部依賴很簡單.一般,咱們使用Hex包管理工具,它能列出在咱們的mix.exs
文件中全部deps函數以內的依賴.學習
def deps do [{:plug, "~> 1.0"}] end
這個依賴的定義是指Plug 1.x.x系列的最新版本已經被Hex添加了.這是由版本號以前的~>
代表的.想知道更多關於制定版本要求的信息,請查閱Version模塊的文檔.測試
通常,穩定的版本會被加入Hex.若是你想要依賴於一個仍在開發階段的外部依賴,Mix也可以管理git依賴:ui
def deps do [{:plug, git: "git://github.com/elixir-lang/plug.git"}] end
你會發現當你添加了一個依賴到你的項目,Mix生成了一個mix.lock
文件,它保證了構建的可重複性.鎖文件必須被導入到你的版本控制系統中,來保證每一個人使用該項目時,依賴的版本與你相同.
Mix提供了許多命令來處理依賴,能夠再mix help
中看到:
$ mix help mix deps # 列出依賴,和它們的狀態 mix deps.clean # 刪除給定的依賴的文件 mix deps.compile # 編譯依賴 mix deps.get # 獲取全部最新版本的依賴 mix deps.unlock # 解鎖給定的依賴 mix deps.update # 更新給定的依賴
最經常使用的命令是mix deps.get
與mix deps.update
.獲取依賴以後,它會自動編譯.你能夠經過mix help deps
或查看Mix.Task.Deps模塊的文檔,來獲取更多關於deps的信息.
#內部依賴
內部依賴是特定於你的項目的.它們一般在你的項目/公司/機構以外就沒有意義.多數時候,出於技術,經濟仍是業務上的緣由,你想要保持它們的私用性.
若是你有一個內部依賴,Mix支持兩種操做方法:git倉庫或雨傘計劃.
例如,若是你添加kv
項目到一個git倉庫,你只須要在你的deps代碼中按順序列出它們就能使用:
def deps do [{:kv, git: "https://github.com/YOUR_ACCOUNT/kv.git"}] end
若是倉庫是私有的,你可能須要指定一個私有URLgit@github.com:YOUR_ACCOUNT/kv.git
.任什麼時候候,Mix都會獲取到它,只要你有合適的憑證.
在Elixir中不是特別推薦使用git依賴.記住運行時和Elixir生態系統已經提供了應用的概念.因此,咱們但願你能常常地將你的代碼打碎成多個應用,它們可以在本地組合,即便是在單個項目中.
然而,若是將每一個應用做爲獨立的項目添加到git倉庫,你的項目會變得很難維護,由於你會花費大量時間來管理這些git倉庫,而不是寫你的代碼.
出於該緣由,Mix支持了"雨傘計劃".雨傘計劃容許你建立一個包含着許多應用的項目,它們所有都放在一個單個的源代碼倉庫裏.這就是下一部分咱們將探索的方法.
讓咱們建立一個新的Mix項目.項目名稱是kv_umbrella
,這個新項目中既有已存在的kv
應用,也有新的kv_server
應用.它的目錄結構會是這樣:
+ kv_umbrella + apps + kv + kv_server
有趣的地方是Mix爲這樣的項目提供了許多便捷性,例如可以用一句命令來編譯和測試apps
中全部的應用.然而,即便它們在apps
中是排列在一塊兒的,它們之間仍然是解耦的,因此你能夠隨意獨立地構建,測試和部署每一個應用.
讓咱們開始吧!
#雨傘計劃
讓咱們使用mix new
開始新項目.這個新項目名爲kv_umbrella
,建立時咱們還須要傳遞一個--umbrella
選項.不要在已存在的kv
項目中建立這個新項目!
$ mix new kv_umbrella --umbrella * creating .gitignore * creating README.md * creating mix.exs * creating apps * creating config * creating config/config.exs
從打印出的信息中,咱們看到不多的文件被生成.生成的mix.exs
文件也不一樣.讓咱們來看看(註釋已刪除):
defmodule KvUmbrella.Mixfile do use Mix.Project def project do [apps_path: "apps", build_embedded: Mix.env == :prod, start_permanent: Mix.env == :prod, deps: deps] end defp deps do [] end end
使得該項目於以前的項目不一樣的緣由就是apps_path
:項目定義中的"apps"
條目.這意味着該項目會像一個雨傘同樣運做.這樣的項目沒有源文件或測試,儘管他們能夠由本身的依賴(不與孩子們共用).咱們將在apps目錄中建立新應用.
讓咱們進入apps目錄,並開始構建kv_server
.這一次,咱們將傳送--sup
旗幟,它會讓Mix保證爲咱們自動生成一個監督樹,而不是像以前那樣手動構建:
$ cd kv_umbrella/apps $ mix new kv_server --module KVServer --sup
生成的文件與咱們一開始爲kv
所生成的類似,只有一些不一樣.讓咱們打開mix.exs
:
defmodule KVServer.Mixfile do use Mix.Project def project do [app: :kv_server, version: "0.1.0", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", lockfile: "../../mix.lock", elixir: "~> 1.3", build_embedded: Mix.env == :prod, start_permanent: Mix.env == :prod, deps: deps] end def application do [applications: [:logger], mod: {KVServer, []}] end defp deps do [] end end
首先,由於咱們是在kv_umbrella/apps
中生成的這個項目,Mix自動檢測到了雨傘結構並添加了四行代碼到項目定義中:
build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", lockfile: "../../mix.lock",
這些選項意味着全部依賴將被簽出至kv_umbrella/deps
,而且它們會分享相同的構建,配置和鎖文件.這保證了整個雨傘結構中依賴只會被獲取並編譯一次,而不是每一個應用都要.
第二個改變是mix.exs
中的application
函數:
def application do [applications: [:logger], mod: {KVServer, []}] end
由於咱們傳送了--sup
旗幟,Mix自動添加了mod: {KVServer, []}
,將KVServer
指定爲了咱們的應用回調模塊.KVServer
將會啓動咱們的應用監督樹.
事實上,讓咱們打開lib/kv_server.ex
:
defmodule KVServer do use Application def start(_type, _args) do import Supervisor.Spec, warn: false children = [ # worker(KVServer.Worker, [arg1, arg2, arg3]) ] opts = [strategy: :one_for_one, name: KVServer.Supervisor] Supervisor.start_link(children, opts) end end
注意它定義了應用回調函數,start/2
,並使用了Supervisor
模塊,而不是定義一個名爲KVServer.Supervisor
的主管,內聯地定義一個主管很方便!你能夠經過閱讀Supervisor模塊文檔來獲取更多關於這種主管的信息.
咱們已經能夠試試咱們的第一個雨傘孩子.咱們能在apps/kv_server
目錄中運行測試,可是並不有趣.讓咱們轉到雨傘項目的根文件並運行mix test
:
$ mix test
運行成功!
因爲咱們但願kv_server
最後能使用咱們在kv
中定義的功能,因此咱們須要將kv
做爲一個依賴添加到咱們的應用中.
#傘內依賴
Mix提供了一個簡單的機制來使一個傘孩子可以依賴於另外一個.打開apps/kv_server/mix.exs
並修改deps/0
函數:
defp deps do [{:kv, in_umbrella: true}] end
上述代碼使得kv
能夠做爲一個:kv_server
中的依賴.咱們能夠導入kv
中定義的而模塊,但不會自動啓動:kv
應用.因此,咱們也須要在application/0
中列出:kv
:
def application do [applications: [:logger, :kv], mod: {KVServer, []}] end
如今Mix將會保證:kv
應用在:kv_server
啓動以前啓動.
最後,複製咱們已經構建了的kv
應用到咱們的雨傘項目中的apps
目錄裏.最終的目錄結構是和咱們以前提到的同樣:
+ kv_umbrella + apps + kv + kv_server
如今咱們只須要修改apps/kv/mix.exs
來包含咱們以前在apps/kv_server/mix.exs
中看到的雨傘條目.打開apps/kv/mix.exs
並添加到project
函數:
build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", lockfile: "../../mix.lock",
如今你能夠在雨傘的根目錄運行mix test
來對兩個項目進行測試了.歐耶!
記住,雨傘項目是一個幫助你組織和管理應用的便捷方法.apps
目錄中的應用仍然是互相解耦的.它們之間的依賴必須被明確列出.它們能夠被共同開發,可是若是須要的話,能夠獨立地被編譯,測試和部署.
#總結
本章咱們學習了更多關於Mix依賴和雨傘項目的內容.咱們決定構建一個雨傘項目,是由於咱們認爲kv
和kv_server
是隻在本項目中有用的內部依賴.
將來,咱們將寫一些應用,你會注意到它們能夠被提取到一個簡潔的單元中,而後被不一樣的項目使用.這時,就應該使用Git或Hex依賴了.
這裏有一些問題,當處理依賴時你能夠問本身.開始:這個應用在此項目以外還有意義嗎?
- 若是沒有,使用帶傘孩子的雨傘項目 - 若是有,該項目是否能夠分享到你的公司/組織以外? - 若是不行,使用私有git倉庫. - 若是能夠,將你的代碼push到git倉庫並常用Hex發佈.
咱們的雨傘項目已經構建並運行了,如今讓咱們開始編寫服務器.