Dobrze, jesteśmy już płynni w analizie statycznej naszej aplikacji, pisania supervisor i tak sobie poruszania się po mix. Pora więc zacząć zagłębiać się trochę bardziej w to co daje nam mix a co umożliwi nam płynne pisanie aplikacji.
Na samym początku poznaliśmy pierwszy typ aplikacji jakie możemy stworzyć z wykorzystaniem mix – po prostu mix new. Kilka tygodni temu zaś poznaliśmy drugi typ aplikacji tworzonych za pomocą mix new, tym razem z parametrem --sup przy tworzeniu aplikacji z wykorzystaniem mix. Parametr ten stworzył nam szablon z kodem który inicjalizował Supervisor i w którym mogliśmy wstawiać nasze własne worker i supervisor. Nic specjalnego, a jednak trochę mniej do pisania. Z tej opcji będziemy pewnie nie raz korzystać, albo przynajmniej ja będę :)
Dziś poznamy trzecie i ostatni typ aplikacji jakie oferuje nam mix (domyślnie oferuje) mix new z parametrem --umbrella. Użyty ma pierwszeństwo na --sup, i podanie tych dwóch parametrów na raz niweluje --sup. To co robi --umbrella to tworzy nam projekt projektów. W świecie .NET nazywamy taki projekt solution lub jak to w Polsce mówią solucje (i o dziwo to jest ok…). Czyli miejsce, które wie o wszystkich pozostałych projektach, jest wstanie nimi zarządzać, przekazywać zależności jak i gromadzić zależności zewnętrzne (taki nuget packages for solution).
Operacja:
mix new eu --umbrella
Wygeneruje nam dużo mniej plików niż standardowy mix new. Po pierwsze, wygeneruje nam on katalog apps w którym będziemy gromadzić nasze projekty/aplikacje. Po drugie nie wygeneruje on nam testów ani żadnych libów itp. Testy są per aplikacja (patrz zdanie wyżej Po pierwsze) ale można je uruchamiać z poziomu eu. Po trzecie, to co nam zostało wygenerowane różni się zawartością od tego co normalnie mamy.
Czyli operacja stworzenia projektu eu wygeneruje nam output:
* creating .gitignore * creating README.md * creating mix.exs * creating apps * creating config * creating config/config.exs Your umbrella project was created successfully. Inside your project, you will find an apps/ directory where you can create and host many apps: cd eu cd apps mix new my_app Commands like "mix compile" and "mix test" when executed in the umbrella project root will automatically run for each application in the apps/ directory.
Co fajne, operacja ta mówi nam dokładnie co możemy zrobić i jak to będzie działało. Prawie to samo co ja napisałem tylko że w jakimiś obcym języku którego nikt nie rozumie ;)
Zanim przejdziemy dalej do opisu co tutaj jest nowego i co możemy zrobić, stwórzmy sobie dwie aplikacje, w tym celu:
cd eu/apps mix new pingpong --sup mix new chat
Specjalnie zrobiłem --sup byście zobaczyli czym i czy w ogóle to się różni od tego co robiliśmy przez ostatnie tygodnie, to już zadanie dla was :)
Możemy sprawdzić czy wszystko nam śmiga odpalając z /eu
$ mix compile ==> chat Compiling 1 file (.ex) Generated chat app ==> pingpong Compiling 1 file (.ex) Generated pingpong app $ mix test ==> chat Compiling 1 file (.ex) Generated chat app ==> pingpong Compiling 1 file (.ex) Generated pingpong app ==> chat . Finished in 0.03 seconds 1 test, 0 failures Randomized with seed 960000 ==> pingpong . Finished in 0.03 seconds 1 test, 0 failures Randomized with seed 23000
Możemy też skorzystać z iex tak jak zawsze:
$ iex -S mix
Jak nam to wszystko działa, to możemy przejść dalej.
Umbrella różni się tym od innych normalnych projektów (new i new --sup), że nie ma ona żadnej implementacji, nie jest też aplikacją. Jest po prostu bytem grupującym prywatne zależności.
Jeżeli porównamy sobie pliki mix.exs z projektu new --umbrella z projektem który nie jest częścią ubmberlla, to zobaczymy pewne cechy wspólne:
def project do [apps_path: "apps", # tutaj jest różnica, ścieżka zamiast app: build_embedded: Mix.env == :prod, # tak samo start_permanent: Mix.env == :prod, # tak samo deps: deps] end
apps_path mówi, gdzie znajdą się aplikację. Normalnie mamy tutaj app: który określa nazwę projektu/aplikacji. Zresztą polecam otworzyć sobie plik mix.exs z chat na przykład. Zobaczymy tam resztę “brakujących” kluczy ze standardowego projektu, czyli app:, elixir:, version:. Ale także zobaczymy kilka nowych, które robią tylko jedno, określają wspólną lokalizację dla wszystkich projektów: konfiguracji, build, zależności.
Na przykład config.exs w umbrella zbiera wszystkie pozostałe config.exs a aplikacji w folderze apps. Dzięki czemu, wszystkie aplikacje są tak samo skonfigurowane. Przydatne.
Jeżeli chodzi o zależności to jest to tak, że jest jedno miejsce ich ściągania, ale nie definiowana!! To bardzo ważne. To znaczy, że nie możemy stworzyć jednej listy zależności i móc ją wykorzystać w każdej aplikacji. Nie, musimy dla każdej aplikacji stworzyć listę zależności. Jednak o tym jak dokładnie zależności działają to jeszcze napiszę osobny post. Tutaj dla naszej wiedzy na razie, możemy zrobić tak by nasz projekt chat, wymagał pingpong. By to zrobić w chat mix.exs należy podmienić deps/0 na:
defp deps do
[{:pingong, in_umbrella: true}]
end
To spowoduje, że zanim w ogóle chat wystartuje, :pingpong będzie już odpalony i działał sobie w tle.
I to chyba tyle jeżeli chodzi o projekty typu umbrella. Reszta rozbija się o to czym jest Mix.Project, use Application i deps. Ale o tym wszystkim sobie opowiemy wtedy kiedy będzie na to pora.
To co jest najważniejsze to, warto zapamiętać, że w elixir też mamy byt grupujący projekty/aplikacje – w .NET jest to solution. Tutaj zwie się to umbrella i mix oraz iex są na tyle inteligentni, że wiedzą, iż działają w kontekście umbrella czy też nie.
Kiedy warto skorzystać z umbrella? To pytanie pozostawię bez odpowiedzi do póki nie poznamy deps. Wtedy się wyklaruje co i jak, lub powinno. Jak na razie ja osobiście nie miałem potrzeby w ogóle korzystać z mix new :) a co dopiero z mix new --umbrella czy też mix new --sup. Wszystko robiłem w iex. Teraz to się pewnie zmieni więc będę też w stanie wam z boju powiedzieć co i jak :)
PS. Stosuje zamiennie Projekt i Aplikacja. Bo to tutaj w kontekstach w których to używałem było jednym i tym samym.















[…] Elixir #23 – Umbrella […]
Comments are closed.