Część 6: Konfiguracja¶
Tłumaczenie wspomagane przez AI - dowiedz się więcej i zasugeruj ulepszenia
Twój plugin ma własne funkcje i obserwator, ale wszystko jest zakodowane na stałe. Użytkownicy nie mogą wyłączyć licznika zadań ani zmienić dekoratora bez edytowania kodu źródłowego i ponownego budowania.
W Części 1 używałeś bloków validation {} i co2footprint {} w nextflow.config, aby kontrolować zachowanie nf-schema i nf-co2footprint.
Te bloki konfiguracyjne istnieją, ponieważ autorzy pluginów wbudowali tę możliwość.
W tej sekcji zrobisz to samo dla własnego pluginu.
Cele:
- Pozwól użytkownikom dostosować prefiks i sufiks dekoratora powitania
- Pozwól użytkownikom włączać i wyłączać plugin przez
nextflow.config - Zarejestruj formalny zakres konfiguracji, aby Nextflow rozpoznawał blok
greeting {}
Co zmienisz:
| Plik | Zmiana |
|---|---|
GreetingExtension.groovy |
Odczyt konfiguracji prefiksu/sufiksu w init() |
GreetingFactory.groovy |
Odczyt wartości konfiguracji do sterowania tworzeniem obserwatora |
GreetingConfig.groovy |
Nowy plik: formalna klasa @ConfigScope |
build.gradle |
Rejestracja klasy konfiguracji jako punktu rozszerzenia |
nextflow.config |
Dodanie bloku greeting {} do testów |
Wskazówka
Jeśli zaczynasz od tej części, skopiuj rozwiązanie z Części 5 jako punkt startowy:
Oficjalna dokumentacja
Szczegółowe informacje o konfiguracji znajdziesz w dokumentacji zakresów konfiguracji Nextflow.
1. Uczynienie dekoratora konfigurowalnym¶
Funkcja decorateGreeting opakowuje każde powitanie w *** ... ***.
Użytkownicy mogą chcieć innych znaczników, ale obecnie jedynym sposobem ich zmiany jest edycja kodu źródłowego i ponowne zbudowanie projektu.
Sesja Nextflow udostępnia metodę session.config.navigate(), która odczytuje zagnieżdżone wartości z nextflow.config:
// Odczytaj 'greeting.prefix' z nextflow.config, domyślnie '***'
final prefix = session.config.navigate('greeting.prefix', '***') as String
Odpowiada to blokowi konfiguracyjnemu w nextflow.config użytkownika:
1.1. Dodanie odczytu konfiguracji (to się nie powiedzie!)¶
Edytuj GreetingExtension.groovy, aby odczytywać konfigurację w init() i używać jej w decorateGreeting():
Spróbuj zbudować:
1.2. Analiza błędu¶
Budowanie kończy się niepowodzeniem:
> Task :compileGroovy FAILED
GreetingExtension.groovy: 30: [Static type checking] - The variable [prefix] is undeclared.
@ line 30, column 9.
prefix = session.config.navigate('greeting.prefix', '***') as String
^
GreetingExtension.groovy: 31: [Static type checking] - The variable [suffix] is undeclared.
W Groovy (i Javie) musisz zadeklarować zmienną przed jej użyciem.
Kod próbuje przypisać wartości do prefix i suffix, ale klasa nie ma pól o tych nazwach.
1.3. Naprawa przez deklarację zmiennych instancji¶
Dodaj deklaracje zmiennych na początku klasy, zaraz po otwierającym nawiasie klamrowym:
Te dwie linie deklarują zmienne instancji (zwane też polami), które należą do każdego obiektu GreetingExtension.
Słowo kluczowe private oznacza, że tylko kod wewnątrz tej klasy może się do nich odwoływać.
Każda zmienna jest inicjalizowana domyślną wartością '***'.
Gdy plugin się ładuje, Nextflow wywołuje metodę init(), która nadpisuje te wartości domyślne tym, co użytkownik ustawił w nextflow.config.
Jeśli użytkownik nic nie ustawił, navigate() zwraca tę samą wartość domyślną, więc zachowanie pozostaje niezmienione.
Metoda decorateGreeting() odczytuje te pola przy każdym wywołaniu.
Wskazówka
Ten wzorzec „deklaruj przed użyciem" jest fundamentalny dla Javy i Groovy, ale może być nieznany, jeśli przychodzisz z Pythona lub R, gdzie zmienne pojawiają się w momencie pierwszego przypisania. Napotkanie tego błędu raz pomaga szybko go rozpoznawać i naprawiać w przyszłości.
1.4. Budowanie i testowanie¶
Zbuduj i zainstaluj:
Zaktualizuj nextflow.config, aby dostosować dekorację:
Uruchom pipeline:
Dekorator używa teraz niestandardowego prefiksu i sufiksu z pliku konfiguracyjnego.
Zwróć uwagę, że Nextflow wyświetla ostrzeżenie „Unrecognized config option", ponieważ nic nie zadeklarowało jeszcze greeting jako prawidłowego zakresu konfiguracji.
Wartość jest nadal poprawnie odczytywana przez navigate(), ale Nextflow oznacza ją jako nierozpoznaną.
Naprawisz to w Sekcji 3.
2. Uczynienie licznika zadań konfigurowalnym¶
Fabryka obserwatorów tworzy je obecnie bezwarunkowo. Użytkownicy powinni mieć możliwość całkowitego wyłączenia pluginu przez konfigurację.
Fabryka ma dostęp do sesji Nextflow i jej konfiguracji, więc to właściwe miejsce do odczytu ustawienia enabled i decydowania, czy tworzyć obserwatory.
Fabryka odczytuje teraz greeting.enabled z konfiguracji i zwraca pustą listę, jeśli użytkownik ustawił tę wartość na false.
Gdy lista jest pusta, żadne obserwatory nie są tworzone, a hooki cyklu życia pluginu są po cichu pomijane.
2.1. Budowanie i testowanie¶
Przebuduj i zainstaluj plugin:
Uruchom pipeline, aby potwierdzić, że wszystko nadal działa:
Ćwiczenie
Spróbuj ustawić greeting.enabled = false w nextflow.config i uruchom pipeline ponownie.
Co zmienia się w wyjściu?
Rozwiązanie
// Konfiguracja dla ćwiczeń z tworzenia pluginów
plugins {
id 'nf-schema@2.6.1'
id 'nf-greeting@0.1.0'
}
greeting {
enabled = false
}
Komunikaty „Pipeline is starting!", „Pipeline complete!" oraz informacja o liczbie zadań znikają, ponieważ fabryka zwraca pustą listę, gdy enabled ma wartość false.
Sam pipeline nadal działa, ale żadne obserwatory nie są aktywne.
Pamiętaj, aby ustawić enabled z powrotem na true (lub usunąć tę linię) przed kontynuowaniem.
3. Formalna konfiguracja z ConfigScope¶
Konfiguracja Twojego pluginu działa, ale Nextflow nadal wyświetla ostrzeżenia „Unrecognized config option".
Dzieje się tak, ponieważ session.config.navigate() tylko odczytuje wartości — nic nie poinformowało Nextflow'a, że greeting jest prawidłowym zakresem konfiguracji.
Klasa ConfigScope wypełnia tę lukę.
Deklaruje, jakie opcje akceptuje Twój plugin, ich typy i wartości domyślne.
Nie zastępuje wywołań navigate(). Zamiast tego działa obok nich:
flowchart LR
A["nextflow.config<br/>greeting { ... }"] --> B["ConfigScope<br/><i>declares valid options</i>"]
A --> C["navigate()<br/><i>reads values at runtime</i>"]
B -. "validates &<br/>documents" .-> A
C -- "provides values to" --> D["Plugin code<br/><i>factory, extension</i>"]
style B fill:#e8f5e9,stroke:#4caf50
style C fill:#e3f2fd,stroke:#2196f3
Bez klasy ConfigScope navigate() nadal działa, ale:
- Nextflow ostrzega o nierozpoznanych opcjach (jak już widziałeś)
- Brak autouzupełniania w IDE dla użytkowników piszących
nextflow.config - Opcje konfiguracji nie są samodokumentujące się
- Konwersja typów jest ręczna (
as String,as boolean)
Zarejestrowanie formalnej klasy zakresu konfiguracji usuwa ostrzeżenie i rozwiązuje wszystkie trzy problemy.
To ten sam mechanizm, który stoi za blokami validation {} i co2footprint {} używanymi w Części 1.
3.1. Tworzenie klasy konfiguracji¶
Utwórz nowy plik:
Dodaj klasę konfiguracji z wszystkimi trzema opcjami:
- Mapuje na blok
greeting { }wnextflow.config - Wymagany interfejs dla klas konfiguracji
- Zarówno konstruktor bezargumentowy, jak i konstruktor przyjmujący Map są potrzebne, aby Nextflow mógł tworzyć instancje konfiguracji
@ConfigOptionoznacza pole jako opcję konfiguracji;@Descriptiondokumentuje je dla narzędzi
Kluczowe punkty:
@ScopeName('greeting'): Mapuje na blokgreeting { }w konfiguracjiimplements ConfigScope: Wymagany interfejs dla klas konfiguracji@ConfigOption: Każde pole staje się opcją konfiguracji@Description: Dokumentuje każdą opcję dla wsparcia serwera językowego (importowane znextflow.script.dsl)- Konstruktory: Potrzebne są zarówno konstruktor bezargumentowy, jak i konstruktor przyjmujący Map
3.2. Rejestracja klasy konfiguracji¶
Samo utworzenie klasy nie wystarczy.
Nextflow musi wiedzieć o jej istnieniu, więc rejestrujesz ją w build.gradle obok pozostałych punktów rozszerzenia.
Zwróć uwagę na różnicę między rejestracją fabryki a punktów rozszerzenia:
extensionPointswbuild.gradle: Rejestracja w czasie kompilacji. Informuje system pluginów Nextflow'a, które klasy implementują punkty rozszerzenia.- Metoda
create()fabryki: Rejestracja w czasie wykonania. Fabryka tworzy instancje obserwatorów, gdy workflow faktycznie startuje.
3.3. Budowanie i testowanie¶
Zachowanie pipeline'u jest identyczne, ale ostrzeżenie „Unrecognized config option" zniknęło.
Uwaga
GreetingFactory i GreetingExtension nadal używają session.config.navigate() do odczytu wartości w czasie wykonania.
Żaden z tych fragmentów kodu nie uległ zmianie.
Klasa ConfigScope to równoległa deklaracja, która informuje Nextflow'a o dostępnych opcjach.
Obie części są potrzebne: ConfigScope deklaruje, navigate() odczytuje.
Twój plugin ma teraz taką samą strukturę jak pluginy używane w Części 1.
Gdy nf-schema udostępnia blok validation {}, a nf-co2footprint udostępnia blok co2footprint {}, używają dokładnie tego wzorca: klasy ConfigScope z adnotowanymi polami, zarejestrowanej jako punkt rozszerzenia.
Twój blok greeting {} działa w ten sam sposób.
Podsumowanie¶
Nauczyłeś się, że:
session.config.navigate()odczytuje wartości konfiguracji w czasie wykonania- Klasy
@ConfigScopedeklarują dostępne opcje konfiguracji; działają oboknavigate(), a nie zamiast niego - Konfigurację można stosować zarówno do obserwatorów, jak i funkcji rozszerzenia
- Zmienne instancji muszą być zadeklarowane przed użyciem w Groovy/Javie;
init()wypełnia je wartościami z konfiguracji podczas ładowania pluginu
| Przypadek użycia | Zalecane podejście |
|---|---|
| Szybki prototyp lub prosty plugin | Tylko session.config.navigate() |
| Plugin produkcyjny z wieloma opcjami | Dodaj klasę ConfigScope obok wywołań navigate() |
| Plugin przeznaczony do publicznego udostępnienia | Dodaj klasę ConfigScope obok wywołań navigate() |
Co dalej?¶
Twój plugin ma teraz wszystkie elementy pluginu produkcyjnego: własne funkcje, obserwatory śladów i konfigurację dostępną dla użytkowników. Ostatnim krokiem jest przygotowanie go do dystrybucji.