sobota, 26 grudnia 2015

Technologia Java Web Start - co i jak?

TL;DR Jeśli nie korzystałeś nigdy z technologi Java Web Start (pliki JNLP) i jeśli nie musisz tego robić, to spokojnie możesz nie czytać dalej - nie obrażę się. Jest to zamierająca technologia i niedługo nie będzie wspierana w nowszych przeglądarkach (zobacz: The Final Countdown for NPAPI). Jeśli jednak korzystałeś / musisz skorzystać z tej technologi, to pewnie [mam nadzieję] dowiesz się czegoś ciekawego z tego i kolejnych artykułów.

Czym jest Java Web Start? Popatrzmy na dokumentację Javy SE.


Powinniście kojarzyć powyższy widok. Zazwyczaj korzystamy z Java SE API, natomiast Web Start jest zdefiniowany trochę wyżej po lewej, zaraz koło Applet'ów - a to nie wróży nic dobrego.


Java Web Start pozwala nam na uruchamianie javowych aplikacji standalone, bezpośrednio po kliknięciu na link’a na stronie www. Nie jest potrzebna żadna instalacja. Jest to wygodny sposób na dystrybuowanie wśród użytkowników najnowszej wersji naszego oprogramowania standalone - wejdźcie na stronę X, kliknijcie link Y i uruchomi się najnowsza wersja oprogramowania z którego [niestety] musicie korzystać. Jest to coś innego niż aplety, bo aplikacja uruchamia się po za przeglądarką.

Jak to działa? Po kliknięciu na link ściągany jest plik JNLP, który jest on w formacie XML’owym. Generalnie plik ten zawiera informację,  co ma uruchomić, skąd pobrać JAR’y, parametry uruchomieniowe itd. Aby całość zadziałała, musimy mieć jakąś Javę zainstalowaną na docelowej maszynie klienckiej.

Tyle teorii. Moim zdaniem, ta technologia świetnie sprawdza się z tutorialem do Swinga, gdzie za pomocą jednokliku możemy odpalić przykład ze strony i zobaczyć efekt. Wystarczy kliknąć na poniższą ikonkę:

https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/CelsiusConverterProject/CelsiusConverter.jnlp



I to by było na tyle. Jeśli chodzi o jakieś bardziej skomplikowane aplikacje, to już może nie być tak różowo. Oracle nigdy jakoś szczególnie nie dbał o jakość tej technologii, czasem wprowadzał niekompatybilne zmiany, zaostrzał security itd.

Największą jednak bolączką programistów zmuszonych do korzystania z tej technologi jest niepewność, na której wersji wirtualnej maszyny Javy będzie odpalona aplikacja. Póki jest to proste demo (tutorial do Swinga), to żadnych problemów nie powinno być. Gdy jednak stworzyliśmy kolosa, który z jakiś powodów działa tylko na konkretnej wersji JVM’a, to zaczynają się schody.

Gdy zdefiniujemy w naszym pliku JNLP, że aplikacja ma się odpalić na Javie 1.7, a user będzie miał zainstalowaną Javę 1.8, to może zobaczyć poniższy komunikat:


Ten i inne screeny otrzymałem grzebiąc w plikach JNLP edytora UML’a: ArgoUML, udostępniającego link do uruchomienia za pomocą Web Start'a.

Czyli aplikacja w tym wypadku uruchomi się na Javie 1.8. W przypadku, gdy mamy w systemie zainstalowane kilka wersji Javy, to użytkownik będzie miał możliwość wyboru, na której się uruchomi.

Jeszcze innym problemem, może być posiadanie przez użytkownika starszej wersji Javy. Jeśli zdefiniujemy, że aplikacja ma się tylko odpalać na wersji 1.8.0_50, a będziemy mieć zainstalowaną starszą (1.8.0_28), to dalej nie mamy pewności, na której się uruchomi - patrz komunikat poniżej.


Jak dobrze pamiętam, to jeszcze jest możliwość, że Web Start będzie próbował ściągnąć nowszą wersję JRE i zainstalować. Jest to spory problem w dużych firmach, gdzie korpo ludki mogą nie mieć (albo raczej nie powinni mieć) uprawnień do instalowania nowych rzeczy na swojej maszynie.

Inną niedogodnością jest jeszcze konieczność podpisywania swoich aplikacji. Od którejś wersji Javy, własne certyfikaty (self signed) są z domysłu blokowane. Trzeba więc albo zdobyć porządny certyfikat od zaufanego wystawcy (czytaj zapłacić), albo skonfigurować userom maszyny tak, aby mogli otwierać aplikacje z zaufanych źródeł.

Jak widać jest sporo tej babraniny, aby całość doprowadzić do ładu i składu. Spójrzmy zatem na kolejne fragmenty przykładowego pliku JNLP. Pozwoliłem sobie bazować na pliku z ArgoUML, ale dorzuciłem też parę ciekawych rzeczy, których tam nie ma zdefiniowanych.
<?xml version="1.0" encoding="utf-8"?>
<!-- JNLP File for launching ArgoUML with WebStart -->
<jnlp
  spec="1.0+"
  codebase="http://argouml-downloads.tigris.org/maven2"
  href="http://argouml-downloads.tigris.org/jws/argouml-latest-stable.jnlp">

Całość będzie zawierać się w tagu jnlp. Możemy w nim zdefiniować atrybut codebase, który będzie naszym bazowym URL’em przy pobieraniu JAR’ów.

Bardzo ciekawy jest atrybut href. Jeśli jest on zdefiniowany, to po uruchomieniu pobranego pliku JNLP (czy to w przeglądarce, czy bezpośrednio z dysku), to Web Start pobierze ten plik jeszcze raz ze zdefiniowanego tutaj adresu i jego będzie interpretował! Jeśli wprowadzimy jakieś zmiany lokalnie w pliku JNLP, ale będzie istniał atrybut href, to nic nam to nie da! Dla celów produkcyjnych warto ustawić ten parametr, na pewno utrudni on życie początkujących hackerom.
<information>
    <title>ArgoUML Latest Stable Release 0.34</title>
    <vendor>Tigris.org (Open Source)</vendor>
    <homepage href="http://argouml.tigris.org/"/>
    <description>ArgoUML application.
                 This is the latest stable release.
    </description>
    <description kind="short">ArgoUML 0.34</description>
    <icon href="http://argouml.tigris.org/images/argologo16x16.gif" width="16" height="16" />
    <icon href="http://argouml.tigris.org/images/argologo32x32.gif" width="32" height="32" />
    <icon href="http://argouml.tigris.org/images/argologo64x64.gif" width="64" height="64" />
    <offline-allowed/>
  </information>

Dalej mamy definicje, które są gdzieś tam wyświetlane podczas uruchamiania aplikacji, czyli tytuł, wydawca, strona domowa, opis, ikonka itp. Ostanie ustawienie (offline-allowed) definiuje nam, że docelowa aplikacja może działać, gdy nie mamy połączenia z netem. Jest jeszcze możliwość tworzenia skrótu na pulpicie, menu start i inne pierdoły.
  <security>
    <all-permissions/>
  </security>
Tutaj definiujemy, co nasza aplikacja może, a co nie. Jeśli jest to okienko swingowe z tutoriala, to nic nie potrzebujemy. Gdy chcemy zapisywać pliki na dysku itp, to potrzebujemy dostęp, najlepiej do wszystkiego. Dokładnie takie same seciurity (ale w trochę innej formie zapisu), musi być zdefiniowane w Manifeście w JAR’ze zawierającym klasę, którą będziemy uruchamiać (z metodą main()).
  <resources>
    <j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se” 
             initial-heap-size=„64m" 
             max-heap-size=„512m" 
             java-vm-args="-ea -Xincgc"/>

Następnie mamy definicję na jakiej wersji Javy ma być odpalona docelowa aplikacja. W specyfikacji 6.0 JNLP zamiast „j2se" może pojawić się „java".

Wersja może być zdefiniowana na wiele sposobów. Możemy podać dokładnie (np.: 1.7, 1.4.2, 1.4.2_04, 1.5.0-beta2), albo większe równie niż (np.: 1.5+, 1.4.2+). Można również podać kilka wersji kolejno wg. preferencji.

Gdy chcemy jakiejś egzotycznej wersji, musimy podać atrybut href.

Na koniec możemy jeszcze zdefiniować ustawienia pamięci i przekazać jakieś flagi do JVM’a.
    <jar href="http://argouml-downloads.tigris.org/maven2/antlr/antlr/2.7.7-3/antlr-2.7.7-3.jar"/>
    <jar href="http://argouml-downloads.tigris.org/maven2/org/argouml/argouml-euml/0.34/argouml-euml-0.34.jar"/>

Dalej definiujemy nasze zależności, które Web Start ma ściągnąć. Zależności są cache’owane, więc jak podbijamy wersję biblioteki, to warto zmienić nazwę pliku. Gdy nie podamy pełnej ścieżki do pliku, to będzie ona budowana na podstawie codebase (w tag’u jnlp).
    <property name=„argouml.modules" value=";org.argouml….."    />
</resources>

W ten sposób definiujemy sobie właściwości wspólne dla wszystkich platform. Muszą one jednak się zaczynać od "javaws." lub "jnlp.”. Ta powyższa definicja z ArgoUML wg. mnie nie zadziała. Jeszcze niektóre predefiniowane propertisy (np.: http.agenthttp.keepAlive) można zdefiniować w ten sposób.

To były właściwości wspólne dla wszystkich systemów operacyjnych. Mamy jeszcze możliwość zdefiniowania właściwości specyficznych dla konkretnej platformy, np.:
  <resources os="Windows" arch="amd64">
     <property name="jnlp.abc" value=„xyz"/>
  </resources>

  <resources os="Mac OS X" arch="x86_64">
     <property name="jnlp.abc" value=„123"/>
  </resources>

Jeszcze na koniec pozostaje nam punkt wejścia do aplikacji:
<application-desc main-class=„com.mycompany.myapp.MainApp">
   <argument>arg1</argument>
   <argument>arg2</argument>
</application-desc>

Tutaj możemy dodatkowo przekazać argumenty do aplikacji. Pełen opis tego co możemy zrobić w pliku JNLP można znaleść tutaj: JNLP File Syntax.

I to już wszystko jeśli chodzi o sam plik JNLP. Przygotowujemy taki plik, wrzucamy na serwer, umieszczamy do niego link, podpisujemy nasze JAR’y, robimy je możliwe do ściągnięcia i już możemy cieszyć się Web Startem. Brzmi prosto, ale na pewno takie nie jest. W kolejnym artykule opiszę, jak można sobie trochę ułatwić życie.

poniedziałek, 21 grudnia 2015

33rd Degree 4 Charity we Wrocławiu

Keep things in memory with Cache, Mateusz Herbut

Mateusz na początku przedstawił ciekawą historię, odnośnie tego, dlaczego się zainteresował cache’m i kiedy został zdefiniowany standard JSR-107 - JCache. Fajnie się całość zbiegła z datami z filmu "Powrót do przyszłości", co prelegent dobrze wykorzystał na slajdach.

Mateusz bardzo fajnie przedstawił na diagramach sekwencji różne techniki działa cache'a:
  • Cache Aside
  • Read Through
  • Write Through
  • Write Back
  • Write Behind
  • Refresh Adead

Pierwsze trzy techniki z pośród wymienionych są zdefiniowane przez standard JSR-107, a pozostałe są wspierane dodatkowo przez niektóre implementacje.

Cache Aside jest najprostszy. Klient (aplikacja) sprawdza najpierw, czy wartość jest dostępna w cache’u. Gdy nie, to aplikacja sama odczytuje wartość ze źródła prawdy (dysku, bazy danych, etc.) i jeśli chce, to ją wrzuca do cache’a.

W metodzie Read Through to cache, a nie aplikacja kliencka, jest odpowiedzialna za odczyt wartości ze źródła prawdy i jej zapamiętaniu u siebie na później.

W podejściu Write Through to cache zapisuje wartość do źródła prawdy (synchronicznie) i zapamiętuje u siebie.

Write back zapisuje dane do źródła prawdy, dopiero wtedy gdy dana wartość jest usuwana z cache’a. Podejście to jest często stosowane w procesorach (L1, L2 cache) i wartości te mogą być niespójne ze źródłem prawdy (pamięć RAM). O unieważnieniu cache’a decyduje cache provider.

Przy Write behind klient zapisuje do cache’a i cache asynchronicznie rozpoczyna zapisywanie do źródła prawdy. Gdy w międzyczasie, ktoś będzie chciał odczytać wartości, to dostanie je bezpośrednio z cache’a.

W ostatniej metodzie Refresh Ahead cache decyduje podczas odczytu, czy wartość trzeba odświeżyć, czy nie.

Dalej było jeszcze o 3ch rodzajach operacji jakie mogą być wywoływane na cache’u:
  • Pessimistic locking
  • Lock free
  • Optimistic locking
ale tu już nie będę przedstawiał, które są które.

Bardzo fajna, mięsista prezentacja. Uwagi odnośnie sposobu prezentowania  przekazałem wieczorem bezpośrednio Mateuszowi.

-XX:+UseG1GC, Jakub Kubrynski

Następnie Jakub Kurbyński ładnie omówił Garbage collector G1, który na być domyślny w Javie 9. Prelegent fajnie przeszedł przez to w jaki sposób jest zorganizowana pamięć w Javie i jakie to ma konsekwencje dla algorytmów odśmiecania. Stopniowo powoli odkrywaliśmy nowe pomysły w sposobach organizacji pamięci i algorytmów odśmiecających.

W G1 mamy wiele faz, ale dokładniej były omawiane 4:
  • Young GC
  • Concurrent cycle
  • Mixed GC
  • Full GC
Young GC to odśmiecanie młodej generacji, odpalane po zapełnieniu wszystkich regionów typu Eden. Jest ono wykonywane równolegle i zatrzymuje naszą aplikację. Concurrent Cycle bazuje na wynikach poprzedniej fazy i stara się znaleźć regiony łatwe do odśmiecenia i je oznacza. Mixed GC uwalnia te obszary z poprzedniej fazy. Czyści on pamięć zarówno z młodej generacji, jaki i starej. Najgorzej, gdy dojdziemy do Full GC (jak go zobaczymy w logach), gdyż on odśmieca całą pamięć i zajmuje sporo czasu, bo wykonuje się jednowątkowo. Powinniśmy tego unikać.

Fajne było podsumowanie, jak tuningować G1. Najlepiej ustawić:
-XX:MaxGCPauseMillis=250
lub na inną empiryczną wartość. Wtedy G1 będzie starał się nie przekroczyć zadanego czasu na odśmiecanie. Oczywiście gdy wartość będzie zbyt mała to się to nie uda. Złą stroną tuningu jest natomiast ten slajd:

czyli flagi których należy się wystrzegać ;)

Jeszcze inne dobre praktyki to:

A do przeglądania logów warto skorzystać z GCViewer, JVisualVM i Mission Control.

Nagranie z Confitury, polecam sobie obejrzeć:


Później była przerwa obiadowa, po której na prezentację Tomka Dziurko "Brzydka Pani od HR radzi…” po raz N-ty nie chciało mi się iść (widziałem na YT), a konkurencyjny temat mnie nie zachęcił. Filmik z prezentacji Tomka poniżej:



Liquibase - zarządzanie zmianami w relacyjnych bazach danych, Marcin Stachniuk

W kolejnym slocie przyszedł czas na moją prezentację. Grono zainteresowanych było niewielkie, bo w drugiej sali w tym czasie mówili o mikroserwisach po raz 144. Slajdy (trochę zaktualizowane od ostatniego razu) poniżej.



Ze zmian (po za kolorkami dopasowanymi do konferencji) to istnieje łatwiejszy sposób na wprowadzenie Liquibase'a do istniejącego projektu, niż ten który przedstawiałem na WrocJUG'u. Można skorzystać z komendy changeLogSync, która to tworzy i wypełnia danymi z changelog'a tabele potrzebne do działania biblioteki (DATABASECHANGELOG i DATABASECHANGELOGLOCK), a same zmiany nie są wykonywane. Po więcej szczegółów zapraszam na stonę Liquibase'a: Adding Liquibase on an Existing project.

Drugą wartością dodaną do prezentacji jest moje subiektywne porównanie Flyway'a i Liquibase'a, ale kot nie był niech żałuje.

Java 9, Arkadiusz Sokołowski

Prelegent pokazał parę nowości które nas czeka w kolejnej wersji Javy. Było oczywiście o REPLu i modułach, czyli projekcie Jigsaw i jak to na nas wpłynie. Prezentacja była ok, ale gdzieś już coś o nowościach słyszałem...

Java developer meets AngularJS/JavaScript: real-world projects’ experiences, Marek Matczak

Prelegent pokazywał z początku popularność różnych języków programowania, gdzie górował JavaScript i Java. Marek proponował te dwa języki do obecnych projektów, a dokładniej Spring-Boot’a i AngularJS’a.

Prelegent przedstawił, jakie są możliwości połączenia tych dwóch światów, od strony budowania aplikacji. Jedno podejście, to łączenie części frontend'owej z buildem Maven’owym. Można do tego wykorzystać maven-assembly-plugin, który buduje zzipowaną aplikację kliencką, a później za pomocą exec-maven-plugin można uruchomić node.js’a. A całość do WAR’a można wrzucić za pomocą: maven-war-plugin’a.

Drugie podejście proponowane przez Marka to wykorzystanie exec-maven-plugin’a do budowania frontendu w trakcie fazy generate-sources. Zasoby te wrzucamy do src/main/resources/static, czyli tam gdzie standardowo Spring Boot się ich spodziewa.

Całość jest dostępna na GitHubie jako Open Application Standard Platform (OASP).

Z ciekawostek, które mi utkwiły, to warto się przyjrzeć Google JavaScript Style Guide i Idiomatic JavaScript, aby wiedzieć jak dobrze pisać kod w JavaScript’cie.

Warto też na przyszłość przyjrzeć się Isomorphic JavaScript. Dzięki temu, będziemy mogli wyrenderować stronę HTML po tronie backend'u, co pozwoli nam np. na szybsze ładowanie się strony głównej naszej aplikacji.

Muszę się również przyjrzeć Gulp’owi, gdyż on ma wbudowane reverse proxy.

Dzień 2
On-heap cache vs. Off-heap cache, Radek Grębski

Drugi dzień zaczął się bardzo mięsistą prezentacją na temat pamięci off-heap, czyli pamięci po za standardowym heap’em Javowym. Jest to pamięć, która nie jest zarządzana przez Garbage Collector, można w niej zapisywać tylko tablice bajtów (korzystająć ze standardowego API) i sami musimy zajmować się jej zwalnianiem.

Generalnie bardzo polecam tą prezentację, jest dostępne nagranie z Confitury 2015 jak i kod na GitHubie: https://github.com/rgrebski/confitura2015


Trochę podsumowując prezentację:
Aby zaalokować pamięć w Javie, można skorzystać z następujących klas: HeapByteBuffer (na stercie [heap], do 2 GB), DirectByteBuffer (po za stertą, do 2 GB), MappedByteBuffer (po za stertą, do 2 GB, pamięć perzystowana), Unsafe.allocateMemory() (więcej niż 2 GB).

Pierwsze 3 klasy mogą allokować do 2 GB ponieważ jako argument przyjmują int’a, który ich ogranicza. Bardzo ciekawą klasą jest MappedByteBuffer, która tworzy buffer w pamięci, który może być zapisywany do pliku na dysku. Ma on tą przewagę nad wszystkim innym, że w przypadku całkowitego crash’u maszyny wirtualnej zapis i tak się powiedzie. Operacja ta jest zapewniana przez system operacyjny.

Chcąc allokować pamięć większą niż 2 GB to już trzeba korzystać z Unsafe’a. Korzystanie z tej klasy nie jest łatwe i wygląda jakby sam Chuck Noris ją pisał. Właściwie ta klasa z definicji miała być dostępna tylko dla „zaufanego kodu”, czyli do wewnętrznego użytku przez Javę. Ale coś poszło nie tak i obecnie masa frameworków i bibliotek z niej korzysta. Co gorsza to klasa ma być niedostępna w Javie 9, więc będzie ciekawie. Sporo kodu trzeba będzie przepisać, albo znaleść haka, aby się dostać do odpowiedniego modułu.

Dalej było o Chronicle Map. Jest to mapa, która jest zapisywana po za stertą. Jest też perzystowalna, dzielona pomiędzy osobnymi procesami JVM (również po sieci). Jedynym minusem jest fixed size, tzn. musimy wiedzieć jak duże będą nasze obiekty. I tak dla String’ów i kolekcji musimy za pomocą @MaxSize zdefiniować jak maksymalnie długie będą nasze teksty i jak wielkie kolekcje w obiektach. Gdy przekroczymy granicę to dostaniemy błąd. Obiekty zapisujemy do bloków o stałej wielkości - trochę pamięci się marnuje, ale dostęp do niej jest łatwiejszy.

Dalej było sporo porównań szybkości działania Mapy i Chronicle Mapy. Następnie prelegent opowiedział jeszcze z grubsza o Hazelcas’cie i Redisie, które również porównał z Chronicle Map.

Purely functional data structures, Tomasz Kaczmarzyk

Na początku zaczęło się o tym jak w językach funkcyjnych są zaimplementowane Listy, że składają się z głowy i ogona, że ogon wykorzystuje dokładnie tą samą strukturę co pierwotna lista itd. Kto się uczył Skali, lub innego języka funkcyjnego, to na pewno kojarzy koncept.

Póżniej było już ciekawiej, o tym jak jest zbudowana kolejka w językach funkcyjnych, w której można dodawać elementy na końcu. W standardowej liście jest to bardzo kosztowna operacja. Kolejka wprowadza pewne ciekawe pomysły, jak może ona być wewnętrznie zorganizowana, aby efektywnie przeprowadzać operacje na niej, mi.in. dodawania elementu na końcu. Ten fragment prezentacji był bardzo fajny.

Następnie było o tym jak wewnętrznie jest zorganizowany Git i jaka to jest ładna struktura danych. Temat był mi już wcześniej znany, więc mnie aż tak nie zachwycił jak poprzednia część.

Prelegent miał bardzo fajne slajdy (pisane kredą po tablicy), z ładnymi animacjami przejścia.

Sane Sharding with Akka Cluster, Michał Płachta

Tutaj było mnóstwo programowania na żywo, które działało! Prelegent się dobrze do tego przygotował.

Na początek napisał pojedynczego aktora obsługującego jakieś zapytania i zrobił test wydajności. Następnie, razem z publicznością, udoskonalał rozwiazanie… Implementowaliśmy system rozdzielający paczki na taśmociągu w jakimś magazynie.

Jako drugi krok, prelegent dorzucił drugiego aktora, który tylko podejmował decyzję o przeznaczeniu paczki. Następnie pojawili się kolejni aktorzy i to już bardzo przyspieszyło obsługę zapytań. Na koniec był jeszcze przedstawiony Akka cluster, aby można było to łatwo skalować na więcej maszyn.

Kod z prezentacji jest dostępny tutaj: https://github.com/miciek/akka-sharding-example. Warto przejść sobie po commit'ach i zobaczyć jak się aplikacja rozwijała.

Recepta na retrospekcję z finezją, Wòjcech Makùrôt

Retrospekcje są wpisane w Agile Manifesto jako dwunasty punkt:
At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.
czyli:
W regularnych odstępach czasu zespół analizuje możliwości poprawy swojej wydajności, a następnie dostraja i dostosowuje swoje działania do wyciągniętych wniosków.
Prelegent podał i opowiedział na przykładach swoje 10 punktów, które trzeba spełnić, aby mieć dobrą retrospektywę. Postaram się streścić, jak ja to zrozumiałem.
  • Trzeba się dobrze przygotować. Spisać sobie plan spotkania, załatwić wszystkie niezbędne pomoce materialne, poszukać inspiracji, aby nie było nudno.
  • Wprowadzamy jakiegoś IceBreak’era, aby rozmawiało się na luzie. Można odwrócić krzesła w sali, aby ludzie musieli zrobić coś innego. Prowadzący spotkanie (facylitator) może być niemerytoryczny - do niego należy moderacja i czasem pacyfikacja spotkania. Najważniejsze jest zdanie innych.
  • Sprawdzamy, czy z poprzedniej retrospekcji udało nam się zrealizować jakieś postanowienia. Jeśli nic się nie udało, to powinniśmy przerwać i zastanowić się dlaczego się nie udało.
  • Możemy opowiedzieć historyjkę, odnośnie tego co działo się w ostatnim sprincie. Budujemy przez to naszą wspólną świadomość.
  • Grupowanie i priorytetyzowanie problemów - powinniśmy zajmować się tylko tymi najważniejszymi problemami.
  • Dziel i rządź, czyli z którymi problemami jesteśmy zdolni sobie poradzić, i które będą miały największy wpływ na poprawę naszej sytuacji.
  • Analiza przyczyn, dlaczego coś nie działa. Tutaj możemy skorzystać z metody 5x dlaczego, ość Ishikawy
  • Planowanie naprawy, czyli: co trzeba zrobić, jak, kto będzie za to odpowiedzialny i na kiedy. Nie warto brać więcej niż 4 tematy do naprawy, bo to może być niemożliwe do zrealizowania.
  • Celebracja tego do czego udało się dojść, czyli warto podziękować za współpracę, nagrodzić jakoś uczestników, wyjść na piwo...
  • Śledzenie postępów w kolejnej iteracji, czyli sprawdzanie wykonania zadań.
Jako źródło inspiracji, warto spojrzeć na retrospectivewiki.org i blog.accentient.com/upgrade-your-sprint-retrospective-meetings oraz do książki Agile Retrospectives.

Slajdy z wystąpienia:


Refactoring meets big money, Michal Gruca

Prelegent przedstawił 3 możliwe podejścia do refactoringu:
  • Codzienny refactoring
  • Pisanie całości od nowa
  • Przepisywanie modułów i podmienianie
Tylko jak to wszystko wytłumaczyć i sprzedać biznesowi? Warto zdecydować się na mierzenie jakiś metryk kodu. Można wziąć jakieś Sonarowe metryki dobrych projektów open source, porównać z metrykami naszych projektów, przełożyć na kasę i strać się wytłumaczyć, że to jest ważne. Warto zrobić sobie sceeena tych metryk z naszego projektu, aby później, po serii refaktoringów, zobaczyć czy i ile się poprawiło.

Warto też, przed pójściem do biznesu, trochę się przygotować. Można stworzyć jakieś prototypowe rozwiazanie i pokazać, że ono przynosi nam jakąś wartość. Przykładowo przyspieszymy build’a albo release’a.

Prelegent polecał do przeczytania fane case study, jak to Soundcloud przechodził na mikroserwisy.

Common fallacies of micro services, Marcin Matuszak

Prelegent w ciekawy sposób podszedł do tego, w jaki sposób obecnie są wynoszone pod niebiosa mikroserwisy, kontrargumentując potencjalne zalety jakie nam daje to podejście. I tak możliwość pisania każdego mikroserwisu w innym języku jest kiepski, bo jak ktoś napisze coś w bardzo egzotycznym języku (którego mało kto zna) i później się zwolni z pracy, to trzeba będzie nauczyć się tego języka, aby utrzymywać kod.

Monolityczne aplikacje wcale nie są takie złe. Są łatwe do pisania testów, w deploymencie i utrzymaniu. Jak rozmawiamy o mikroserwisach, to się skupiamy na tym, że mają być serwisy i że mają być małe. A zapominamy że mają sie komunikować po sieci, co przysparza masę dodatkowych problemów. Jeśli zepsuliśmy aplikację monolitową, to również i zepsujemy mikroserwisy.

Podsumowując całość, była to bardzo fajna konferencja, w końcu coś ciekawego i większego zawitało do Wrocławia. Nie miałem wysokich oczekiwań co do prelekcji, a okazały się one na dobrym poziomie. Byłem więc pozytywnie zaskoczony tą konferencją. Jednocześnie sam miałem okazję wystąpić i wyświetlać swoje slajdy po raz pierwszy na kinowym ekranie.

czwartek, 5 listopada 2015

Po dbconf 2015 i 69 spotkaniu Wrocławskiego JUG'a

Ostatnio, miesiąc po poprzednim wystąpieniu na WrocJUGu, miałem okazję dzielić się swoją wiedzą na temat ElasticSearch’a. Najpierw było to w ramach dbconf - konferencji dla bazodanowców, a później na swoim podwórku, czyli Wrocławskim JUG’u. Początkowo kolejność miała być inna (najpierw WrocJUG, potem dbconf), ale nie wyrobiłem się z przygotowaniem. Nie wpłynęło to jednak na jakość obydwu wystąpień.

W ramach dbconf byłem właściwie tylko na swoim wykładzie i imprezach integracyjnych, gdyż nie czuję się typowym bazodanowcem. Zresztą konferencja odbywała się w Jurze Krakowsko-Częstochowskiej, więc była okazja aby zwiedzić okolicę.

Co do samego wykładu, to poszło mi chyba całkiem dobrze. Płynnie uruchamiałem wcześniej przygotowane przykłady i było trochę pytań z sali. Końcówkę musiałem jednak już gnać i pominąć parę szczegółów, bo niestety sztywne ramy czasowe nie pozwoliły mi na przekazanie wszystkiego. Po prezentacji było trochę pytań, na które już odpowiadałem po za salą.

Z całego pośpiechu zapomniałem zabrać zasilacza, ale na szczęście organizatorzy mi go odesłali, więc mogłem kilka dni później poprowadzić ten sam temat we Wrocławiu.

W ramach JUG’a pierwszy raz spotkaliśmy się w nowym miejscu tj. w Sanatorium Kultury na rynku. Bardzo fajne miejsce, ze sceną jak w teatrze i klimatycznym oświetleniem. Było trochę problemów z mikrofonem, ale jak już wymienili baterię, to działało.

Na spotkanie była chętna ponad setka ludzi, ale na sali była już tylko połowa z tego.

Na szczęście nie ograniczał mnie czas i cała prezentacja zajęła mi 2 godziny! Było sporo pytań z publiczności, zwłaszcza od Kamila i jeszcze jednej osoby, która wcześniej pracowała sporo z Apache Solr. Nie na wszystkie umiałem odpowiedzieć, bo nie jestem specjalistą w temacie i nie spotkałem się z niektórymi omawianymi przypadkami.

Udało mi się na szczęście zebrać trochę feedbacku, tego dobrego i złego, więc uważam, że warto go tutaj zapisać, aby za jakiś czas zrobić sobie retrospekcję i sprawdzić czy się coś poprawiło. Dziękuję wszystkim dzielącym się ze mną swoją opinią!

Uwagi:

  • “Podczas przełączania slajdów machałeś ręką, jakbyś chciał rapować” - fakt, widać to na nagraniu, do poprawki.
  • “Warto by mieć ciągle agendę gdzieś z boku, bo często pytania wybiegały mocno w przód (dotyczyły tematu który nie był jeszcze omawiany)” - choć nie spotkałem się z takim podejściem na konferencjach, ale to może mogę być pierwszy ;) Rzeczywiście można wywiesić agendę gdzieś z boku i wtedy osoby zadające pytanie mogą 2 razy się zastanowić, czy to aby na pewno jest dobry moment na dane zapytanie. Można jeszcze wydrukować kartki z agendą i umieścić na siedzeniach jak w teatrze lub operze, ale to jeszcze wyższy poziom ;)
  • “Dużo pytań o specyficzne tematy, których ktoś kto pierwszy raz spotyka się z narzędziem i tak nie zapamięta” - to fakt. Było sporo szczegółowych pytań, których osoby początkujące i tak nie zapamiętają. Z drugiej strony osoby zaawansowane też chcą coś wynieść z prezentacji, więc wypada odpowiedzieć. Ja się cieszę, że czasem była zażarta dyskusja, bo sam się przez to czegoś dowiedziałem. Fajne jest również to, że uczestnicy odpowiadają sobie nawzajem. Z drugiej strony liczne pytania trochę zaburzają tok prezentacji. Ciężko tutaj znaleźć złoty środek:/ Może powinienem rzadziej pytać, czy są jakieś pytania?
  • “Zabrakło przykładów z poziomu Javy” - no fakt skupiłem się na zapytaniach RESTJSON’owych, a zapomniałem, że jesteśmy na Java User Group. Dobra uwaga, powinno być więcej kodu z Javie. Chyba coś muszę dodać w kolejnej wersji (jeśli będzie kolejna wersja).
  • “Lepiej niż miesiąc wcześniej, gdzie puszczałeś wcześniej nagrany film” - tak, tym razem były przygotowane przykłady, które odpalałem na żywo. W prezentacji o Liquibasie bardzo dużo mogło pójść nie tak, więc lepiej było nagrać krótki filmik. Jest więc jakiś postęp.
  • “Widownia mogłaby bardziej uczestniczyć w tworzeniu przykładów” - mogłem pytać się np. jaki film utworzyć w indeksie, co poszukać itp. Do poprawki.
  • “Przydałyby się jeszcze jakieś fajerwerki. Nawet najlepsza prezentacja jeśli trwa długo, potrzebuje przerywnika” - był żart o masturbacji… Ale fakt zapomniałem o zasadzie, która kiedyś była dla mnie bardzo ważna, aby był jakiś śmieszny przerywnik w trakcie. Zwłaszcza, że prezentacja zajęła mi 2 godziny. Nie wiedziałem wcześniej, że może mi to tyle zająć.
  • “Sekcja "teoretyczna" powinna zostać lepiej omówiona” - nie wiem co miałbym jeszcze omawiać w kwestii teoretycznej… postawiłem bardziej na praktykę.
  • “Wymowa: "bede", "must", "fuzzy", "schema” i język potoczny: "klepał w klawiaturę", “mianowicie” - chyba trochę za dużo oglądania Pana Wiesława Wszywki. Nad wymową niektórych słów muszę trochę popracować, ale języka potocznego nie zmienię - innym osobom luźny styl prowadzenia prezentacji się podobał (wliczając w to mnie), więc tak już zostanie. Nie chcę gadać jak nudny wykładowca.
  • “Próby kodowania na żywo kiepsko wychodzą” - fakt chciałem coś tam małego zakodować w trakcie - pod wpływem pytania z publiczności - i były z tym pewne problemy. Podpowiadania składni brak, nie robiłem tego wcześniej, po za tym inne obszary mózgu są odpowiedzialne za mówienie i za pisanie - nie jestem w stanie robić tego równocześnie.


Była jeszcze masa pozytywnych komentarzy. Większości bardziej się podobało niż nie podobało. Nie będę jednak przytaczał tych pozytywnych komentarzy.

A już za niecały miesiąc, 33 degree 4 charity zawita do Wrocławia. Będę tam mówił o Liquibase, czyli mój temat z 67 spotkania WrocJUG. Trzeba będzie go trochę zmodyfikować, aby zmieścić się w wyznaczonym czasie. I będę mógł zobaczyć swoją prezentację na dużym ekranie :) Już dzisiaj wszystkich serdecznie zapraszam!

Poniżej slajdy dla zainteresowanych odnośnie ElasticSearch’a: