Dostarczanie danych przez REST i ich aktualizacja

0

Sprawa wygląda tak że mam serwis który wczytuje z pliku yaml pewne dane tekstowe i wystawia je na endpoint w stylu localhost:8080/info
Inne serwisy mogą sobie zrobić request i dociągnąć te informacje i wszystko śmiga ładnie.
Problem w tym że mam też drugi endpoint który może te informacje aktualizować i wówczas na endpoincie GET localhost:8080/info powinny być oczywiście zwrócone nowe dane.
Jeśli serwis zostanie zresetowany to wracamy do wartości domyślnych.

Aktualnie mam Spring'a który tworzy taką konfigurację na podstawie pliku:

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties("Info.default")
class InfoProperties {

    private String url;
    private String port;
    private String somethingElse;

//getter

Do tego jest klasa serwisu która trzyma taki obiekt i ma 2 metody:


@Service
class InfoProvider {

    private InfoProperties properties;

    public InfoProvider (InfoProperties properties) {
         this.properties = properties;
    }   

  InfoProperties getInfo() {
        return properties;
    }

    void updateProperties(InfoProperties properties){
        this.properties = properties;
    }
}

I to w sumie działa. W testach jak robie kilka zapytań na get to najpierw mam domyślne wartości a potem po update dostaje wartości zaaktualizowane. Ręcznie testowałem i też jest ok.
Wydawałoby się więc że wszystko ładnie śmiga ale @jarekr000000 często krytykuje springowe beany i tak się zastanawiam czy to się może wykrzaczyć w jakichś sytuacjach

Jeśli to jest faktycznie bezsensu to może jakieś inne propozycje?

0

To dziwne, że działa bo nie powinno. Tzn. jak masz szczęście to działa.
Konkretnej to getInfo powinno często dawać stare dane. Zasymuluj to pod obciążeniem na kilku wątkach.

0

@jarekr000000: właśnie spodziewam się że to może nie działać bo z tego co kojarzę to Spring dla każdego requesta tworzy nowy wątek z max pulą 200 (by default) więc między wątkami to się może zwyczajnie rozjechać. Natomiast potestowałem (chociaż fakt że bez większego obciążenia) i działa stąd też pomyślałem że może o czymś nie wiem.

Pytanie więc jak to sensownie poprawić? DB nie widzę sensu stawiać bo to bardzo mała ilość danych więc może jakiś inny pomysł?

2

Volatile. To takie minimum.

Jakkolwiek zrobienie symulacji i sprawdzenie jak to działa uważam, za sensowne ćwiczenie. Mozesz te watki odpalić w testach, bez bawet http. Od razu wołaj serwis.

0

Ok faktycznie to ma sens natomiast intryguje mnie trochę to zdanie To takie minimum.
Można z tym zrobić coś więcej?

0

Skoro synchronized na updateProperties() jest niewystarczające, to podpinam się pod temat. Jak to przetestować wielowątkowo, żeby sprawdzić, że w odpowiedzi zawsze są aktualne i poprawne dane? JMeterem da się coś takiego ogarnąć?

0

synchronized nie działa, bo sychronizuje tylko metodę updateProperties, getInfo w teorii będzie zwracać błędne wyniki.

0

Skoro używasz RESTa zasadne wydaje się użycie ETAGa do takiej funkcjonalności, przykładowy opis jak skonfigurować to w Springu https://www.baeldung.com/etags-for-rest-with-spring

0

AtomicReference nie wystarczy?

0

@puradawid: AtomicReference to volatile + kilka dodatkowych metod atomicznych, więc wystarczy. Zresztą kod mówi sam za siebie: https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/util/concurrent/atomic/AtomicReference.java#L60

1 użytkowników online, w tym zalogowanych: 0, gości: 1