W połowie roku 2006 Scott James Remnant z Canonical Ltd. ogłosił powstanie nowego demona, który ma zastąpić wysłużony demon init z pakietu Sysvinit. Główną różnicą a zarazem nowością, jaka miała cechować Upstart, było podejście do uruchamiania usług oparte na zdarzeniach. Dzięki niemu za pomocą Upstart można uruchamiać usługi w sposób równoległy, a nie szeregowy, jak w większości* skryptów startowych wykorzystujących demon z pakietu sysvinit.
Niestety przez długi czas rzeczywistość nie wyglądała tak różowo, jak w pierwotnych planach — z różnych powodów nie działał mechanizm sprawdzania zależności pomiędzy skryptami, więc Upstart nie działał lepiej niż Sysvinit (nie dało się uruchamiać równolegle usług tak, żeby mieć pewność, że będą działały). Ten stan rzeczy zmienił się na szczęście wraz z wydaniem Upstart 0.5.
Jednak Casey Dahlin (człowiek, który “naprawił” Upstart) nie jest zadowolony z aktualnego mechanizmu działania opartego na zdarzeniach i zaproponował wprowadzenie lepszego mechanizmu działania opartego na stanach. Dzięki takiemu podejściu będzie możliwa większa kontrola nad tym, co w danym momencie powinno być uruchomione w systemie. Nowa droga została nazwana UpState, jej kod źródłowy można podziwiać w repozytorium Casey’a w postaci skryptu języka Ruby o długości 534 linii kodu. Złośliwi mogą twierdzić, że Ruby nie nadaje się do pisania takich rzeczy, ale deweloperzy dystrybucji Pardus udowodnili już, że można wykorzystać skrypty Pythona jako initscript.
Dzięki zastosowaniu automatu skończonego znacząco wzrosła też czytelność skryptów startowych — oto przykład:
require 'state' include UpState HdAvail = State.new_type("hdAvail", [Event.new("DevKit_FoundHD")], [], [:uid, :name, :blkdev]) FstabAvail = State.new_type("fstabLine", [Event.new("Can_Mount", {:mount_str => /.*/})], [], [[:uid, :name, :blkdev], :mount_str]) Mount = State.new_type("mount", [Event::Epsilon], [Dependency.new(HdAvail, {:uid => /.*/}), Dependency.new(FstabAvail, {:mount_str => /.*/})]) events = [ ["DevKit_FoundHD", {:uid => "1234", :name => "myhd", :blkdev => "/dev/sda1"}], ["Can_Mount", {:uid => "1234", :mount_str => "/home"}], ["Can_Mount", {:uid => "1234"}], ] State.print_all_color events.each do |x| State.process_event Event.new(*x) State.print_all_color end
Szanowni czytelnicy na pewno docenią prostotę i genialność nowego rozwiązania. Można mieć tylko nadzieję, że już wkrótce skrypty startowe popularnych dystrybucji zaczną wykorzystywać tę nową technologię, aby szybko startować systemy linuksowe.
* Napisałem większości — wiem, że istnieją wyjątki, więc proszę się nie czepiać i nie ciągnąć za słówka
Dodaj komentarz