typo, hide counter on empty pages, add short title

This commit is contained in:
2026-06-07 16:22:00 +02:00
parent 334776da5a
commit a525fe60dd
6 changed files with 21 additions and 17 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
== Systemy współdzielenia dokumentów w czasie rzeczywistym
Budując rozwiązania związane z równoczesnym tworzeniem i modyfikacją tekstu przez więcej niż jednego użytkownika, musimy rozważyć wyzwania napotykane w aktualizacji tworzonego dokumentu, gdzie każdy klient posiada lokalną kopię i nanosi na nie własne zmiany, ale też w międzyczasie musimy nanieść zmiany od pozostałych klientów. W takim systemie mówimy wtedy o zbieżności danych@cite:eventually_consistent - czyli zapewnieniu tego samego stanu między każdym klientem. W przypadku edycji tekstu skupię się na ewentualnej zbieżności, która uwzględnia posiadanie rozbieżnych kopii tego samego źródła danych u każdego z klientów przez pewien czas. Dopiero gdy zostanie zakończona edycja tekstu, zmiany zostają propagowane i nanoszone do pozostałych klientów. Finalnie każdy klient po czasie posiada identyczną kopię dokumentu. Ze strony doświadczeń użytkowania jest to skuteczna strategia ze względu na możliwość zapewnienia płynności interfejsu graficznego oraz z pomocą złożonych mechanizmów umożliwia rozwiązywanie konfliktów między kopiami.
Wspomniany model nie jest bez wad. Największym problemem jest istnienie konfliktów, których rozwiązanie klienci muszą ustalić za pomocą dodatkowych strategii. Najeczęściej wykorzystywaną jest Last-Write-Wins (LWW). Rozstrzyga ona konflikty poprzez nanoszenie tylko tej zmiany, która jest uznawana jako ostatnia w kolejności zbioru konfliktujących operacji. Ustalanie kolejności nie jest jasno tutaj zdefiniowane. W systemach baz danych takich jak Cassandra@cite:apache_cassandra_documentation oraz SQL Server P2P@cite:microsoft_sql_server_p2p_replication_documentation każdy zapis otrzymuje własny znacznik czasowy, na podstawie którego wybierany jest najmłodszy wpis i nim nadpisywane zmiany w źródle danych. Zmiany ze starszymi znacznikami porzucane. Zauważalną wadą LWW jest wysokie ryzyko utraty danych w czasie nanoszenia zmian, ponieważ wszystkie konfliktujące starsze zmiany nie brane pod uwagę.
Wspomniany model nie jest bez wad. Największym problemem jest istnienie konfliktów, których rozwiązanie klienci muszą ustalić za pomocą dodatkowych strategii. Najczęściej wykorzystywaną jest Last-Write-Wins (LWW). Rozstrzyga ona konflikty poprzez nanoszenie tylko tej zmiany, która jest uznawana jako ostatnia w kolejności zbioru konfliktujących operacji. Ustalanie kolejności nie jest jasno tutaj zdefiniowane. W systemach baz danych takich jak Cassandra@cite:apache_cassandra_documentation oraz SQL Server P2P@cite:microsoft_sql_server_p2p_replication_documentation każdy zapis otrzymuje własny znacznik czasowy, na podstawie którego wybierany jest najmłodszy wpis i nim nadpisywane zmiany w źródle danych. Zmiany ze starszymi znacznikami porzucane. Zauważalną wadą LWW jest wysokie ryzyko utraty danych w czasie nanoszenia zmian, ponieważ wszystkie konfliktujące starsze zmiany nie brane pod uwagę.
W przypadku tekstu jako typu danych, istnieje specjalny wariant ewentualnej zbieżności - silna ewentualna zbieżność. Ten model wykorzystuje specjalne struktury danych, które zapewniają bezkonfliktowe nanoszenie zmian, a ich skuteczność opiera się na matematycznych dowodach@cite:verifying_strong_eventual_consistency.
+1 -1
View File
@@ -122,7 +122,7 @@ struct NoteInvitation: Identifiable {
caption: [Definicja obiektu reprezentującego zaproszenie do edycji notatki],
)
Ostatnim obiektem jest struktura `Peer` przedstawiona w programie 3.4, która jest opisem aktualnego stanu połączenia wykrytego innej instancji systemu w pobliżu użytkownika. Składa się z wartości enumerowanej opisującej stan połączeniao raz identyfikatorem użytkownika w sieci peer to peer. Implementuja ona protokół `Idenfitiable`, by móc zostać poprawnie użyta do rysowania listy dostępnych klientów w pobliżu użytkownika.
Ostatnim obiektem jest struktura `Peer` przedstawiona w programie 3.4, która jest opisem aktualnego stanu połączenia wykrytego innej instancji systemu w pobliżu użytkownika. Składa się z wartości enumerowanej opisującej stan połączenia wraz z identyfikatorem użytkownika w sieci peer to peer. Implementuje ona protokół `Identifiable`, by móc zostać poprawnie użyta do rysowania listy dostępnych klientów w pobliżu użytkownika.
#let peer_struct = [```swift
struct Peer: Identifiable {
+1 -1
View File
@@ -289,6 +289,6 @@ Weryfikacja wymagań niefunkcjonalnych została uzupełniona o pomiary wydajnoś
Średnie zużycie pamięci RAM przy uruchomionej aplikacji, bez aktywnej sesji edycji, wynosiło 20 MB. Podczas aktywnej sesji peer-to-peer z dwoma połączonymi klientami zużycie wzrastało do 30 MB. Wzrost ten jest spowodowany głównie utrzymywaniem obiektów związanych z sesją `MCSession` oraz obsługą komponentu edycji tekstu `TextEditor`. Nie zaobserwowano wycieków pamięci w trakcie użytkowania.
Obciążenie procesora w stanie spoczynku wynosiło 0-1%, gdzie przedział maksymalny wynosi 0-600%, ze względu na obecność 6 rdzenii, których zużycie, w zakresie 0-100%, się sumuje. Podczas intensywnej edycji tekstu z jednoczesną synchronizacją obciążenie wzrastało do 30-40% na urządzeniu iPhone 16 Pro. Głównym źródłem obciążenia była obsługa edycji tekstu oraz wysyłanie danych przez framework Multipeer Connectivity.
Obciążenie procesora w stanie spoczynku wynosiło 0-1%, gdzie przedział maksymalny wynosi 0-600%, ze względu na obecność 6 rdzeni, których zużycie, w zakresie 0-100%, się sumuje. Podczas intensywnej edycji tekstu z jednoczesną synchronizacją obciążenie wzrastało do 30-40% na urządzeniu iPhone 16 Pro. Głównym źródłem obciążenia była obsługa edycji tekstu oraz wysyłanie danych przez framework Multipeer Connectivity.
Podsumowując - przeprowadzone testy jednostkowe, scenariuszowe oraz wydajnościowe potwierdzają, że zaimplementowana aplikacja spełnia przyjęte wymagania funkcjonalne i niefunkcjonalne. Architektura oparta na protokole `StorageProvider` umożliwiła efektywne testowanie logiki przechowywania, natomiast manualne scenariusze wykazały stabilność komunikacji P2P w typowych warunkach użytkowania.
BIN
View File
Binary file not shown.
+8 -4
View File
@@ -11,14 +11,18 @@
#pagebreak()
#include "Abstract.typ"
#zut-template([
#pagebreak(to: "odd")
#zut-template(
[
#include "Chapters/0. Introduction.typ"
#include "Chapters/1. Theoretical Scope.typ"
#include "Chapters/2. Implementation.typ"
#include "Chapters/3. Tests.typ"
#include "Chapters/4. Summary.typ"
#render-bib()
#pagebreak(to: "odd")
#render-bib()
#pagebreak()
#list-of-figures()
])
],
shorttitle: "Aplikacja do współtworzenia notatek z wykorzystaniem technologii peer-to-peer",
)
+1 -1
View File
@@ -92,7 +92,7 @@
let chapter-locs = query(heading.where(level: 1))
let is-chapter-page = chapter-locs.any(h => counter(page).at(h.location()).first() == pg)
if not is-chapter-page {
if chapter-locs.len() == 0 {} else if not is-chapter-page {
// Tytuł bieżącego rozdziału do nagłówka
let prev = query(heading.where(level: 1).before(here()))
let ch-label = if prev.len() > 0 {