Wpis z mikrobloga

Hej mirki z tagu #programowanie.

Mam problem koncepcyjny. Pracuję nad projektem w którym wymagany jest wpółbieżny dostęp do zasobów przez różnych użytkowników. Całość oparta o Spring Boot, mongoDB, angular.
W skrócie:
Użytkownicy mają listę dokumentów które mogą edytować niezależnie od siebie. Jeżeli jeden użytkownik edytuje tylko jeden dokument wszystko jest ok. Problem powstaje kiedy 2 lub więcej użytkowników będzie chciało edytować ten sam dokument.

Klient chce takie rozwiązanie:
- dać możliwość edycji pierwszemu, resztę poinformować aby czekała aż tamten skończy.

I tutaj leży mój problem, w jaki sposób przechowywać informację o tym, że jakiś użytkownik zaczął edycję dokumentu.
Mogę:
- przy rozpoczęciu edycji przez pierwszego użytkownika wysłać info do innych, że ten dokument jest edytowany (informacja trzymana po stronie klienta )
- trzymać informację przy każdym dokumencie w bazie (np. dodać pole isInEditMode) ale może dojść do sytuacji kiedy użytkownik przestanie edytować dokument a pole w bazie się nie zmieni (np. wyłączy kompa)
- trzymać w pamięci po stronie serwera listę dokumentów które są aktualnie edytowane ( przy dużej liczbie użytkowników może być problem)

Jako kanał synchronizacji wykorzystałem websockety, wiec tutaj nie ma problemu, angular i spring się świetnie dogadują.

Jeżeli ktoś z was pracował nad podobnym problemem prosiłbym o jakieś wskazówki, ewentualnie o jakieś dobre źródła z których mogę się doszkolić.

#programowanie #java #pytanie #spring
  • 11
- trzymać w pamięci po stronie serwera listę dokumentów które są aktualnie edytowane ( przy dużej liczbie użytkowników może być problem)


@t12t12: Jakie problemy? To rozwiązanie brzmi najlepiej.
- trzymać w pamięci po stronie serwera listę dokumentów które są aktualnie edytowane ( przy dużej liczbie użytkowników może być problem)


@t12t12: ta opcja ma chyba tą samą wadę co opcja druga.

Opcja pierwsza też średnia, bo co jeśli jakiś użytkownik zaloguje się do systemu po rozpoczęciu edycji danego dokumentu przez użytkownika?

Ja bym w bazie trzymał informację o tym, że dokument jest edytowany, ale nie w formie boolean tylko timestampa.
@t12t12: Ja zasugerowałbym coś podobnego jak @sosna119 . W bazie trzymasz timestamp ostatniego "heartbeata" info czy jest edytowany czy nie.

Aplikacja, która uzyskała dostęp i edytuje wysyła co X czasu "hearbeat", że jeszcze edytuje.

Serwer, kiedy przychodzi rządanie o edycję, przyznaje dostęp jeśli dokument nie jest edytowany (info w bazie, że nie jest), lub hearbeat nie przyszedł w odpowiednim czasie (np. 3x heartbeat).

Hearbeat może być ustawiony na 1 minutę, 10
@t12t12: Jak korzystasz z websocketów to możesz od tego uzależnić, czy dany użytkownik edytuje dokument. Jak mu zerwie połączenie to znak, że pewnie przestał edytować.
Dodatkowo możesz przy braku aktywności ze strony użytkownika pokazać dajmy na to po 15 minutach komunikat, że jak w ciągu 60 sekund nie naciśnie przycisku, że chce dalej edytować dokument to wyłączysz mu edycje tego dokumentu.
Jak korzystasz z websocketów to możesz od tego uzależnić, czy dany użytkownik edytuje dokument. Jak mu zerwie połączenie to znak, że pewnie przestał edytować.


@stash: Nieprawda to jest :) Aplikacje webowe nie powinny opierać się na stabilności łącza. Przecież możesz z tego korzystać w telefonie albo w pociągu na słabym połączeniu. Zanik może być tymczasowy i do tego czasu aplikacja powinna przechowywać dane lokalnie, żeby wysłać je do serwera jak już
@stash: Wtedy chyba lepszym rozwiązaniem jest to co zasugerowałem wyżej - efekt będzie podobny, a nie trzeba badać websocketów. Właściwie wcale nie trzeba utrzymywać żadnego połączenia.
@sosna119: @t12t12: ja bym to rozwiązał tak ze mamy w bazie pole isInEditMode z timestamp ale informowała by o ostatnim logu od użytkownika aktualnie mającego otwarta bazę i co x-1 czasu użytkownik co ma otwarty plik nadpisuje go pole a ten co chce miec dostęp do dokumenty sprawdza czy to pole ma wartość mniejsza niż aktualna godzina - x i jeśli tak to moze otworzyć plik