Event Sourcing w Javie

Event Sourcing w Javie
TK
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 2 miesiące
  • Postów:342
0

Witajcie,

Chciałbym stworzyć pewien system w Javie oparty na mikrousługach oraz DDD. W związku z tym mam kilka pytań dotyczących Event Sourcingu:

  1. Jakiej technologii najlepiej użyć do Event Sourcingu? Które z dostępnych rozwiązań jest waszym zdaniem najlepsze i jakie w ogóle są?

  2. Które jest najbardziej popularne w systemach napisanych w Javie? Rozwiązanie nie musi być przeznaczone tylko dla aplikacji pisanych w Javie. Bardziej chodzi mi o to z jaką technologią Javowcy się najczęściej spotykają podczas prac z mikrousługami i Event Sourcingiem.

  3. Czy znacie rozwiązania dzięki którym można w Event Storze umieścić zdarzenia w taki sposób aby ich kolejność podczas odtwarzania stanu agregatu ze zdarzeń była inna niż kolejność faktycznego umieszczenia zdarzeń w Event Storze? Chodzi mi o to, że chciałbym mieć aplikacje serwerową i aplikacje klienckie, które z założenia byłyby zdolne do pracy w trybie offline. W sytuacji gdyby jeden użytkownik korzystający z aplikacji offline zmienił dane pewnego dnia powiedzmy o godzinie 18:00 a drugi (korzystający z aplikacji online) zmieniłby te same dane o godzinie 19:00 to podczas synchronizacji o godzinie 20:00 (dane są synchronizowane przez aplikacje działającą wcześniej offline podczas przejścia w stan online) chciałbym mieć zdarzenia poukładane chronologicznie (użytkownik pracujący offline dokonał zmiany wcześniej niż użytkownik pracujący online ale to ten, który pracował online miał dostęp do serwera i z punktu widzenia serwera dokonał zmian wcześniej).

Pytanie trzecie jest bardziej opcjonalne: podczas odpowiadania na ten post nie należy sugerować rozwiązań pod trzecie kryterium.

KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:6 dni
  • Lokalizacja:Silesia/Marki
  • Postów:5505
1

Ad. 1. Chodzi Ci o broker wiadomości? Kafka lub RabbitMQ
Ad. 2. Nie rozumiem pytania
Ad. 3. Synchronizacja stanu bazy po offline to strasznie skomplikiwany problem. W przypadku ogolnym nierozwiązywalny


Mama called me disappointment, Papa called me fat
Każdego eksperta można zastąpić backendowcem który ma się douczyć po godzinach. Tak zostałem ekspertem AI, Neo4j i Nest.js . Przez mianowanie
KA
Niektórzy by się kłócili https://dzone.com/articles/apache-kafka-is-not-for-event-sourcing i pewnie Vaughn Vernon też by sie sprzeciwil
KA
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 2 lata
  • Postów:594
0
edytowany 3x, ostatnio: karsa
OtoKamil
Jemu pewnie nie, mi też nie ale w sumie to bym poczytał :D
KA
Jeden z częstych przykładów na use case to shopping cart
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

Ta opcja 3 brzmi bardzo źle, bo oznacza że można by bardzo łatwo zaburzyć spójność danych i generalnie narobić cudów w systemie, skoro pozwalasz na "modyfikowanie historii", szczególnie z poziomu jakiejś aplikacji klienckiej. Nie wiem co ten system ma robić, ale mocno bym się nad tym zastanowił.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
TK
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 2 miesiące
  • Postów:342
0
KamilAdam napisał(a):

Ad. 1. Chodzi Ci o broker wiadomości? Kafka lub RabbitMQ

Chodzi mi o to aby mógł odtworzyć stan obiektów na podstawie zdarzeń, które zaszły w systemie. Jeżeli więc użytkownik:

  1. Zarejestruje się w systemie i poda swój adres e-mail. Niech to będzie adres X
  2. Później zmieni swój adres e-mail z X na Y
  3. Później zmieni swój adres e-mail z Y na Z

To ja:

  1. Zapiszę gdzieś informację o tym, że doszło do zarejestrowania użytkownika z adresem e-mail X
  2. Zapiszę gdzieś informację o tym, że użytkownik zmienił adres e-mail z X na Y
  3. Zapiszę gdzieś informację o tym, że użytkownik zmienił adres e-mail z Y na Z
  4. Jak trzeba będzie ustalić jaki jest obecny adres e-mail użytkownika to przeczytam wszystkie powyższe zdarzenia i będę wiedział, że aktualny adres e-mail to Z.

Poczytałem trochę, że Kafka może sprostać tym oczekiwaniom ponieważ w Kafce można zapisać sekwencje zdarzeń i ją później przeczytać od początku do końca. Jednak spotkałem się też z krytyką takiego zastosowania i w sumie nie wiem jak to jest (informacje krytyczne mogą nie być już aktualne).

Co do Rabbita to mam trochę większe wątpliwości czy to się do tego nadaje. Nie używałem tego ale kojarzy mi się to bardziej z przesyłaniem komunikatów bez gwarancji, że zostanie zachowana kolejność ich dostarczania no i nie wiem czy można sobie przeczytać od tak cała historie komunikatów od samego początku czy bardziej działa to na zasadzie "masz dostęp do komunikatu, którego jeszcze nie odebrałeś a nie do tych, które kiedyś zostały już dostarczone".

Ad. 2. Nie rozumiem pytania

Załóżmy hipotetycznie, że technologie RabbitMQ, Kafka i Axon spełniają wymagania i można to wykorzystać do Event Sourcingu. Jeżeli np. w projektach tworzonych za pomocą języka Java dominuje technologia Axon (np. w 8 na 10 Javowych projektach korzysta się z Axona, w 1 na 10 z Rabbita i w 1 na 10 z Kafki) to odpowiedź na moje pytanie brzmi "Axon jest najpopularniejsza technologią stosowana do Event Sourcingu w Javowych projektach". Gdyby to RabbitMQ był najbardziej popularną technologią w Javowych projektach to wtedy odpowiedź na moje pytanie brzmi "RabbitMQ jest najpopularniejsza technologią stosowana do Event Sourcingu w Javowych projektach". Sam RabbitMQ nie jest wtedy technologią ściśle powiązaną z Javą tylko technologią, z której mogą korzystać również programiści innych języków no ale jeżeli akurat Javowcy tego zazwyczaj używają to taka byłaby odpowiedź.

Ad. 3. Synchronizacja stanu bazy po offline to strasznie skomplikiwany problem. W przypadku ogolnym nierozwiązywalny

No właśnie odnoszę wrażenie, że przy zastosowaniu Event Sourcingu problem mógłby się znacznie uprościć (tak mi się przynajmniej wydaje na chwilę obecną :))

karsa napisał(a):

a czy na pewno jest Ci to potrzebne?

Jeszcze nie wiem :) Generalnie to chciałem poszerzyć nieco horyzonty więc chętnie wypróbuje :)

Shalom napisał(a):

Ta opcja 3 brzmi bardzo źle, bo oznacza że można by bardzo łatwo zaburzyć spójność danych i generalnie narobić cudów w systemie, skoro pozwalasz na "modyfikowanie historii", szczególnie z poziomu jakiejś aplikacji klienckiej. Nie wiem co ten system ma robić, ale mocno bym się nad tym zastanowił.

Rozumiem Twoje obawy. Jednak jeżeli chodzi o aplikacje kliencką to raczej chciałbym to zorganizować w ten sposób żeby taka aplikacja mogła synchronizować zdarzenia z serwerem tylko wtedy kiedy użytkownik ma odpowiednie uprawnienia do tego. Zakładam tutaj, że albo użytkownikiem nie będzie przypadkowa osoba albo sytuacje, w której użytkownik nie będzie miał możliwości synchronizowania zdarzeń, które mogą mieć wpływ na innych użytkowników.

Zobacz pozostałe 2 komentarze
KA
Zmiany danych users to według mnie zły przykład. Raczej nie chcesz tego w żaden sposób dystrybuować bo dochodzi kontekst gdpr. Zamiast nad event sourcingiem to skupilbym się na event driven, bez myślenia o sourcingu.
KA
Ile zespołów będzie pracować przy tym systemie?
TK
@karsa: na chwile obecną jeden zespół jednoosobowy :) Projekt póki co hobbystyczny. Mam dostęp do serwera, na którym mogę uruchomić Docker-a. System ma na chwilę obecną działać na moje własne potrzeby a w późniejszym czasie się zobaczy czy nadaje się to do czegoś więcej. Mimo wszystko nie chciałbym abyś podchodził do tego jak do małego projektu bo jednym z celów jest poszerzenie horyzontów i w miarę możliwości wolałbym korzystać z narzędzi, które są stosowane w poważnych systemach. Po prostu nie mam doświadczenia ani z DDD ani z mikrousługami wiec chce się temu przyjrzeć.
KA
Microservices w jedną osobę to dość specyficzny pomysł. DDD możesz bawić się w jednej appce.
TK
@karsa: zdaję sobie z tego sprawę :)
AK
  • Rejestracja:ponad 6 lat
  • Ostatnio:dzień
  • Postów:3561
1

Wydaje mi się, że algorytmy biznesowe offline a event sourcing to jest inna bajka - choć w sposób oczywisty widać podobieństwa
Zarazem, o ile algorytmy offline to istotna część realnej pracy w realnym życiu biznesowym, to mocno niedowartościowane teoretycznie.

KamilAdam napisał(a):

Ad. 2. Nie rozumiem pytania

ja też

Ad. 3. Synchronizacja stanu bazy po offline to strasznie skomplikiwany problem. W przypadku ogolnym nierozwiązywalny

Intuicyjnie mi się wydaje, że lekarstwo jest w projekcie dziedzinowym, aby rzeczy ulegały "samonaprawieniu", czy "samosynchronizacji" (idealnie, by nie psuły się wcale)
W każdym razie bardzo daleko od myślenia "weźmy technologię X" i nam załatwi


Bo C to najlepszy język, każdy uczeń ci to powie
edytowany 1x, ostatnio: AnyKtokolwiek
TK
Ujmę trochę prościej drugie pytanie: "jaka technologia do Event Sourcingu jest stosowana najczęściej przez Javowców?" - mam nadzieję, że teraz wszystko jasne :)
KA
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 2 lata
  • Postów:594
2
edytowany 1x, ostatnio: karsa
TK
Zainteresowało :)
KA
o ten issue mi chodziło https://github.com/kbastani/event-sourcing-microservices-example/issues/28 , oczekiwalbym nieco wiecej po kbastani. Koleś ewangelizuje te wszystkie buzzwordy albo robi prezentacje na ten temat jak we wspomnianym issue i taka lipa
Charles_Ray
Bardzo fajny thread, paru mocnych zawodników się wypowiedziało, sporo się można nauczyć. Autor rzeczywiście się trochę zamieszał.
KA
Najlepsze, że kbastani i Richardson mieli chyba o tym prezke X lat wcześniej lol
TK
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 3 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
2
Shalom napisał(a):

Ta opcja 3 brzmi bardzo źle, bo oznacza że można by bardzo łatwo zaburzyć spójność danych i generalnie narobić cudów w systemie, skoro pozwalasz na "modyfikowanie historii", szczególnie z poziomu jakiejś aplikacji klienckiej. Nie wiem co ten system ma robić, ale mocno bym się nad tym zastanowił.

To akurat nie jest żaden problem. Jeśli masz cały system oparty o event sourcing to manipulowanie historią jest oczywiste i (prawie) proste.

Miliony developerów korzystających z gita widzi codziennie, że to działa.
Każdy głupi sieciowy RTS,FPS musi sobie też z tym radzić (o ile nie chcemy aby gracze mieli 2 sekundowy lag).

Problem jest tylko wtedy kiedy częśc systemu nie bazuje na eventach....

A rozwiązaniem jest jak w gicie - najlepiej w evencie podawać do której wersji obiektu się odnosi. Wtedy, w event handlerze można zauważyć, że ktoś nam namieszal i nie zgadza się oczekiwany numer wersji obiektu - można napisać jakiś "conflict solver",

Czasem konflkt będzie trywialny - jeśli inkrementujesz,sumujesz licznik to nie ma problemu.
Czasem będzie trudny - jeden użytkownik dodaje opis do produktu, a drugi go usuwa - rozwiązanie zależy od wymagań biznesowych.

Najbliżej gotowca do CQRS jest dla mnie jest https://www.lagomframework.com/documentation/1.6.x/java/Home.html.
Ale nie wiem na ile trudno by tam zrobić offline handling. Takie rzeczy robiłem dawno temu "ręcznie" (zanim dowiedziałem się, że to jest event sourcing).


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
Zobacz pozostałe 6 komentarzy
jarekr000000
@Shalom: nie do końca - zawsze mamy wszystkie zdarzenia, nic nie znika, więc o konflikcie się dowiemy. Oczywiście to od biznesu zależy czy i na ile dopuszczamy takie offline/online. W totolotku by się nie sprawdziło.
jarekr000000
Przykład z ubezpieczeń - to agenci chodzący po domach z offline bazą klientów i dorzucający dane do systremu CRM (tzw. mutacje polis) po synchronizacji. Raz na rok jest konflikt, bo klient coś podpisał w domu, a potem zadzwonił, że się rozmyslił... - btw. zresztą obecnie w dobie internetu komórkowego - to już bardzo rzadki przypadek.
jarekr000000
Git zakłada szeregowanie zgodne z pushem do remote, a nie zgodne z commitem do lokalnego repo. nie zmieniałeś nigdy historii w gicie? :-)
Shalom
Force push na mastera na remote? Codziennie rano tak robie, zaraz po dropie na produkcyjnej bazie ;) Lepsze na podniesienie ciśnienia niż kawa
jarekr000000
@Shalom git filter-branch a potem push na mastera :-)
Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:mniej niż minuta
0

Git przy commicie zapisuje pełne snapshoty, a nie kompaktowe eventy (diffy). Zachodzi oczywiście deduplikacja danych, by repo gitowe nie zajmowało kosmicznych ilości miejsca na dysku. Diffy w gicie są liczone na żądanie - każdy commit to pełny snapshot, więc jak chcemy porównać dwa commity to wyciągamy te dwa snapshoty i porównujemy. Wadą podejścia gitowego jest to, że czasami silnik do obliczania różnic się myli, np gdy w jednym commicie zarówno zmienimy trochę zawartość pliku jak i jego nazwę to git może nie załapać, że to edycja jednego pliku i zamiast modyfikacji pokaże usunięcie starego pliku i dodanie nowego. SVNy, CVSy i inne starożytne VCSy chyba nie mają takiego problemu. Coś za coś.

Jeśli chodzi o automatyczne rozwiązywanie konfliktów przy rozbieżnościach historii edycji to są do tego specjalne struktury danych (dla stosunkowo wąskiego grona przypadków): https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type

Edycja wycinka historii to moim zdaniem kiepski pomysł, bo przy edycji eventu o timestampie T trzeba:

  • wyrzucić wszystkie snapshoty z timestampem >= T
  • cofnąć się do ostatniego pozostałego snapshotu
  • odegrać od nowa (tzn nanieść zmiany w bazie odpowiadające zawartości eventu) wszystkie eventy o timestampie >= T

Można to porównać do edycji commitu gitowego. Jeśli edytujemy commit zrobiony 5000 commitów temu to trzeba przepisać te 5000 commitów, a to zajmuje czas.

W trakcie przepisywania historii (w sensie: odgrywania zedytowanej historii eventów na bazę danych do odczytu) cały system powinien dalej działać. Co więc robimy jeśli do końca przepisywania jeszcze daleko, a klienci chcą widzieć swoje dane (włączając najnowsze zmiany)? Może stawiamy dwie bazy i się między nimi przełączamy po przepisaniu historii?

Każdy głupi sieciowy RTS,FPS musi sobie też z tym radzić (o ile nie chcemy aby gracze mieli 2 sekundowy lag).

W przypadku gier nie ma potrzeby robienia merge'a. Każdy atrybut można traktować jako osobny plik, który się w całości nadpisuje, a nie merge'uje. Jeśli serwer np przeniesie gracza o wektor (3, 5) (bo tak sobie obliczył na podstawie jego poprzednich ruchów), a potem dostanie sygnał od niego, że naprawdę było (4, 4) to ten drugi sygnał wygrywa i tyle. Last write wins i po temacie.

Druga sprawa to to czy te silniki gier sieciowych robią jakąś skuteczną magię? Filmiki znalezione na szybko na YT zdają się temu przeczyć:

Symulowanie ruchów gracza przez serwer może się sprawdza dla małych lagów, ale przy dużych (np sekundy) mamy znaczny teleporting.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 3x, ostatnio: Wibowit
SA
Pisanie gier w Kotlinie na silniku KorGE to dobry pomysł na poznanie języka? https://korge.org/
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 3 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
1

W aplikacjach biznesowych masz zwykle niezależne strumienie eventów na każdy agregat (właśnie z powodów wydajnościowych/skalowania).
Dlatego raczej tysięcy eventów odgrywać nie musisz.

Co do gier - moja wiedza pochodzi sprzed 15 lat kiedy tematem się zajmowałem (robiłem gre, nawet za pieniądze - chociaż nic z tego nie wyszło na koniec). Dużo wtedy doczytałem, choć w kod żadnej sensownej AAA nie zaglądałem. Ta książka (o ile pamiętam, bo dużo tego kiedyś czytałem) https://helion.pl/ksiazki/perelki-programowania-gier-vademecum-profesjonalisty-tom-3-dante-treglia,ppgvp3.htm
była moją inspiracją w temacie - choć niekoniecznie nazywało się to tam event sourcing (nie pamietam):

Generalnie bez jakiegoś event sourcingu trudno było w czasach internetu z pingiem 1s (20-15 lat temu) zrobić gre sieciową która nie będzie lagowała. RTS to najlepszy przykład - masz 200 jednostek na ekranie, 4 graczy - jedyne co możesz rozsyłać to eventy.
dzieją się wtedy zabawne sytuacje, bo może własnie strzeliłeś z jakiegos BFG... ale wg danych, które przeszły od innego gracza to twoja jednostka zginęła 50ms wcześniej.
Faktycznie w grach jest raczej globalny strumień eventów, a baza danych to kawałek pamięci... i wtedy masz dwie kopie (tak jak piszesz). Jedną z twoimi eventami - to leci na ekran. Drugą (safe), opóźnioną z eventami zatwierdznymi przez master (jeden z graczy zwykle pełni rolę master serwera). Jeśli dojdzie do konfliktu, to robi się klon safe i odtwarza eventy wg. kolejności u mastera.
Ważną rzeczą jest wykrywanie konfliktu - bo większość pomieszania zdarzeń nie wpływa na stan gry - wiec trzeba mieć jakiś checksum stanu gry (wpływają na niego twarde dane - ilość zywych jednostek itp), to że jakaś jednostka jest w nieco innym miejscu można zwykle olać. Jeśli konfliktów będzie dużo to fakycznie jest problem z permanentnym klonowaniem i odtwarzaniem z safe.
Na mniejszą skalę problem jest w grach FPS. To, że gracze lagują i przeskakują po ekranie to mały pikuś - problem jest jak dwóch graczy do siebie strzeli np, z rakiety - może być konflikt, kto zginął. A komuś fraga trzeba dać.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
Wibowit
jak dwóch graczy do siebie strzeli np, z rakiety - może być konflikt, kto zginął - hmm, obaj?
PerlMonk
@jarekr000000: Co to jest aplikacja biznesowa?
KamilAdam
Co to jest aplikacja biznesowa Dobre pytanie. Sam używam tego terminu a jakbym miał podać definicję to nie wiem. Strzelałbym że to na pewno nie gra, tylko zwykła standardowa aplikacja zamawiana przez biznes. Najpewniej działająca na serwerze, ale nie wiem czy to mieści się w ramach definicji
PerlMonk
@KamilAdam: No właśnie. Spotkałem się z terminem "dane biznesowe" w aplikacji. Takie dane są przedmiotem przypadków użycia: login i e-mail to dane biznesowe, implementacja to inna sprawa. Aplikacja zawsze jest do czegoś używana, więc sama w sobie jest przedmiotem jakichś założeń biznesu. Może kwestia użycia...
jarekr000000
@PerlMonk: słuszna uwaga. Jak dla mnie biznesowe jest przymiotnikiem o zerowym znaczeniu semantycznym. Wrzuciłem bez sensu. Taki koloryzator - o kolorze przezroczystym. Aplikacje biznesowe -> aplikacje, logika biznesowa -> logika.
KamilAdam
@jarekr000000: logika biznesowa -> logika, ale jest jeszcze logika aplikacji
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)