Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > pl.comp.programming > #33990 > unrolled thread

Integracja bibliotek event-based

Started byMaciej Sobczak <see.my.homepage@gmail.com>
First post2020-06-08 14:58 -0700
Last post2020-06-14 11:52 -0700
Articles 16 — 3 participants

Back to article view | Back to pl.comp.programming


Contents

  Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-08 14:58 -0700
    Re: Integracja bibliotek event-based heby <heby@poczta.onet.pl> - 2020-06-09 00:32 +0200
      Re: Integracja bibliotek event-based heby <heby@poczta.onet.pl> - 2020-06-09 00:38 +0200
    Re: Integracja bibliotek event-based Mateusz Viste <mateusz@xyz.invalid> - 2020-06-09 09:46 +0200
      Re: Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-09 13:58 -0700
        Re: Integracja bibliotek event-based heby <heby@poczta.onet.pl> - 2020-06-09 23:18 +0200
        Re: Integracja bibliotek event-based Mateusz Viste <mateusz@xyz.invalid> - 2020-06-10 10:56 +0200
          Re: Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-10 14:19 -0700
            Re: Integracja bibliotek event-based Mateusz Viste <mateusz@xyz.invalid> - 2020-06-11 10:37 +0200
              Re: Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-11 11:00 -0700
                Re: Integracja bibliotek event-based Mateusz Viste <mateusz@xyz.invalid> - 2020-06-11 21:58 +0200
                  Re: Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-12 11:55 -0700
                    Re: Integracja bibliotek event-based Mateusz Viste <mateusz@xyz.invalid> - 2020-06-13 09:33 +0200
                      Re: Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-13 12:52 -0700
                        Re: Integracja bibliotek event-based Mateusz Viste <mateusz@xyz.invalid> - 2020-06-14 13:55 +0200
                          Re: Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-14 11:52 -0700

#33990 — Integracja bibliotek event-based

FromMaciej Sobczak <see.my.homepage@gmail.com>
Date2020-06-08 14:58 -0700
SubjectIntegracja bibliotek event-based
Message-ID<5d642286-413d-47db-91b0-c689bbe167f4o@googlegroups.com>
To jest wyciągnięty pod-wątek z wątku o serwerze HTTP.

Powiedzmy, że program używa 3 bibliotek event-based. Żeby nie trzeba było mieć wątków i innych muteksów.
W jednej trzeba zrobić server->next(), w drugiej agent.do_some_work() a w trzeciej worker::process(). Powiedzmy, że te funkcje od razu wychodzą jak nie mają nic do roboty, a jak mają, to szybko robią (bo na nic nie czekają) i też wychodzą.

Co należy zrobić, żeby użyć ich razem w jednym programie?
Takie coś:

while (true)
{
    server->next();
    agent.do_some_work();
    worker::process();
}

jest złe, bo kręci się w kółko i zużywa prąd nawet (zwłaszcza) wtedy, gdy nie ma nic do zrobienia. Nie chcemy tak.

Jakie jest poprawne rozwiązanie dla integracji tych 3 bibliotek?

-- 
Maciej Sobczak * http://www.inspirel.com

[toc] | [next] | [standalone]


#33993

Fromheby <heby@poczta.onet.pl>
Date2020-06-09 00:32 +0200
Message-ID<rbmea1$76l$1@dont-email.me>
In reply to#33990
On 08/06/2020 23:58, Maciej Sobczak wrote:
> Jakie jest poprawne rozwiązanie dla integracji tych 3 bibliotek?

To zależy co robią.

Jeśli ich zadaniem jest coś policzyć i zniknąć to masz dobrze.

Jesli ich zadaniem jest coś policzyć tylko jak będzie potrzeba to od 
tego masz wsparcie OSa i jego pętlę komunikatów. Być może też jakieś 
wątki pod spodem, ale klient o nich nie wie, bibliteka często też nie 
wie. Ogólnie cooperative multitasking bazuje na tym że robisz jak 
przychodzi jakiś event. Systemowy zazwyczaj. Można poprosić aby 
przychodził non-stop jeden za drugim. Każdemu w/g potrzeb.

Oba podejścia są od dziesiątek lat katowane choćby w Qt i masz tam jakiś 
obraz tego jak zrobić 1) (onIdle()) i jak zrobić 2) (push event). Mogą z 
sobą działać bardzo gładko i elegancko.

Mam duże (w sensie wielopoziomoe) algorytmy rozbite na pojednycze kroki 
i popychane z onIdle z głownej pętli. Spadek wydajności jest, ale 
pomijalny, choć oczywiscie wszystko zależy od tego jak realizowany jest 
yeld(). To podejście jest nie dla sztuki, tylko warunki brzegowe 
utrudniają użycie watków. Na szczęscie nie ma najmniejszego problemu, w 
dodatku mogę takie coroutines wrzucić *dynamicznie* do wątku i z niego 
wyjąć kiedy tylko chcę, na przykład w połowie pracy.

Teoretycznie każdy algorytm można przerobić na coroutine za pomocą 
boost::context ale koszt może być wysoki, to wszak przełącza kontekst, 
prawie jak wątek. W przypadku ręcznym najczęściej pasuje jakiś wzorzec 
typu maszyn stanów. Do ogarnięcia w typowych przypadkach, rekurencja 
jest bardziej bolesna, ale niewiele.

[toc] | [prev] | [next] | [standalone]


#33994

Fromheby <heby@poczta.onet.pl>
Date2020-06-09 00:38 +0200
Message-ID<rbmel6$8v8$1@dont-email.me>
In reply to#33993
On 09/06/2020 00:32, heby wrote:
> wie. Ogólnie cooperative multitasking bazuje na tym że robisz jak 
> przychodzi jakiś event. Systemowy zazwyczaj. Można poprosić aby 
> przychodził non-stop jeden za drugim. Każdemu w/g potrzeb.

z grubsza to jest tak:

std::vector< jobs > jobs;

Scheduler::onIdle()
{
	if ( somethingToDo( jobs) )
	{
		sheduleNextOnIdleEvent();
		doSomething( shuffle( jobs ) );
	}
	// stop onIdle callbacks by doing nothing
}

I to samoczynnie się zatrzyma jak coroutines zakończą pracę.

Mechanizm onIdle jest systemowy i jest drugorzędne jak działa.

[toc] | [prev] | [next] | [standalone]


#33995

FromMateusz Viste <mateusz@xyz.invalid>
Date2020-06-09 09:46 +0200
Message-ID<20200609094640.04ee0ae2@mateusz>
In reply to#33990
2020-06-08 o 14:58 -0700, Maciej Sobczak napisał:
> while (true)
> {
>     server->next();
>     agent.do_some_work();
>     worker::process();
> }
> 
> jest złe, bo kręci się w kółko i zużywa prąd nawet (zwłaszcza) wtedy,
> gdy nie ma nic do zrobienia. Nie chcemy tak.

Zdecydowanie nie chcemy. 30 lat temu na 386 to jeszcze uchodziło, bo
program był jeden na raz a i prądożernośćią CPU nikt się nie
przejmował. Dziś trochę wstyd, kiedy po uruchomieniu programu
wentylator w laptopie zaczyna się kręcić. :)

> Jakie jest poprawne rozwiązanie dla integracji tych 3 bibliotek?

To zależy co one mają robić. Skoro mowa o serwerze, to domniemywam że
punktem wejścia jest pojawienie się jakiegoś nowego stanu na
sockecie. Jeśli tak, to sprawa prosta:

for (;;) {
  select(sockfd+1, &socksetr, &socksetw, &socksete, &timeout);
  /* TODO obsługa SIGINT */
  /* TODO obsługa timeout */
  server->next();
  agent.do_some_work();
  worker::process();
}


Mateusz

[toc] | [prev] | [next] | [standalone]


#33999

FromMaciej Sobczak <see.my.homepage@gmail.com>
Date2020-06-09 13:58 -0700
Message-ID<aa97820e-825e-4efe-b403-2c1f496dc7ffo@googlegroups.com>
In reply to#33995
W dniu wtorek, 9 czerwca 2020 09:46:44 UTC+2 użytkownik Mateusz Viste napisał:
> > Jakie jest poprawne rozwiązanie dla integracji tych 3 bibliotek?
> 
> To zależy co one mają robić.

Każda robi coś innego.

> Skoro mowa o serwerze, to domniemywam że
> punktem wejścia jest pojawienie się jakiegoś nowego stanu na
> sockecie.

Ale my nie widzimy tych socketów, bo one są ukryte w tych bibliotekach. Jedna obsługuje HTTP, druga asynchroniczną bazę danych a trzecia odbiera tweety z Twittera. Każda z nich ma zapewne jakieś sockety, ale nie wiemy o tym.

> Jeśli tak, to sprawa prosta:
> 
> for (;;) {
>   select(sockfd+1, &socksetr, &socksetw, &socksete, &timeout);

No więc wcale nie jest prosta, bo nie możemy zrobić tego selecta.

Możemy próbować to, co pokazał heby z onIdle i podobnymi, ale co jak mamy nie jedną, ale właśnie 3 biblioteki? Żadna z nich nie może zablokować żadnej z wywołanych funkcji (to jest błąd u heby[*]), bo to zatrzyma pętlę, a być może pozostałe biblioteki mają wtedy coś do zrobienia.

Więc gramy dalej. :-)

[*] Kurdę, łatwiej się odmienia "u Sebastiana", niż "u heby".

-- 
Maciej Sobczak * http://www.inspirel.com

[toc] | [prev] | [next] | [standalone]


#34002

Fromheby <heby@poczta.onet.pl>
Date2020-06-09 23:18 +0200
Message-ID<rboubi$ikv$2@dont-email.me>
In reply to#33999
On 09/06/2020 22:58, Maciej Sobczak wrote:
> Żadna z nich nie może zablokować żadnej z wywołanych funkcji (to jest błąd u heby[*])

To jest kontrakt. Jesli go złamiesz to masz problem. Więc to nie jest 
błąd, bo jeśli tak to taki sam błąd możesz zrobić w preemptive blokując 
muteks i wyrzucając klucz do kibla.

> [*] Kurdę, łatwiej się odmienia "u Sebastiana", niż "u heby".

To odmieniaj. Eternal Speptember randomicznie podpisuje mi maile, raz 
heby z adresu raz pełnym podpisem. Ch... wie dlaczego. Pewno nie mają 
unit testów ...

[toc] | [prev] | [next] | [standalone]


#34006

FromMateusz Viste <mateusz@xyz.invalid>
Date2020-06-10 10:56 +0200
Message-ID<20200610105625.30b3dad0@mateusz>
In reply to#33999
2020-06-09 o 13:58 -0700, Maciej Sobczak napisał:
> Ale my nie widzimy tych socketów, bo one są ukryte w tych
> bibliotekach.

To jakieś strasznie opakowane te biblioteki, że nie pozwalają dobrać
się do źródłowego socketa.

> Jedna obsługuje HTTP, druga asynchroniczną bazę danych
> a trzecia odbiera tweety z Twittera. Każda z nich ma zapewne jakieś
> sockety, ale nie wiemy o tym.

A co mówi dokumentacja tych bibliotek? Chyba ich autorzy nie zakładają,
że ktoś będzie busy loop tworzył czekając na tweeta?

Jeśli chodzi o asynchroniczną bazę danych, to klient wysłał jakieś
polecenia i czeka na odpowiedź, jednocześnie robiąc coś innego. W
takiej sytuacji wystarczy odczekać chwilę (np. pustym selectem) i
sprawdzać jakimś db_isBusy() czy baza skończyła co miała robić. W
zależności od założeń projektowych tę samą metodę można zastosować dla
tweetów i "obsługi http" (cokolwiek by miało to znaczyć).

Słowem - to samo co sugerowałem wcześniej, tyle że z pustym sockset w
select() i sztywnym timeout, stosownie dobranym by niczego nie
zakorkować. Ale to tylko jeśli biblioteki faktycznie nie udostępniają
jakichkolwiek mechanizmów sygnalizacji swoich potrzeb.

Mateusz

[toc] | [prev] | [next] | [standalone]


#34013

FromMaciej Sobczak <see.my.homepage@gmail.com>
Date2020-06-10 14:19 -0700
Message-ID<e642682f-3296-4377-85b1-4c7dee0359b4o@googlegroups.com>
In reply to#34006
> > Ale my nie widzimy tych socketów, bo one są ukryte w tych
> > bibliotekach.
> 
> To jakieś strasznie opakowane te biblioteki, że nie pozwalają dobrać
> się do źródłowego socketa.

Jest gorzej. To nie muszą być sockety. Np. system QNX ma fajny mechanizm komunikacji IPC, który istnieje poza przestrzenią deskryptorów plików. A ktoś inny będzie się komunikował przez pamięć dzieloną. Itd. Więc nawet gdybyś miał dostęp do bebechów, to i tak nie zapiąłbyś wszystkiego razem jednym selectem.

No i nie możemy zakładać, że socket jest jeden, albo że ciągle ten sam, itd. Straszne komplikacje.

> A co mówi dokumentacja tych bibliotek?

To, co napisałem. Że wymienione funkcje robią robotę i wychodzą albo od razu wychodzą.

> Chyba ich autorzy nie zakładają,
> że ktoś będzie busy loop tworzył czekając na tweeta?

Nie musi być busy loop. Bo możemy też założyć, że w każdej bibliotece jest dodatkowa funkcja wait_for_work(). Albo że te funkcje mają dodatkowy argument, żeby czekać. Tak jest w YAMI4. Wtedy pętla użytkownika nie musi być busy - po prostu blokuje się, jak nie ma nic do roboty.

Ale mamy 3 takie funkcje. I co teraz?

> W
> takiej sytuacji wystarczy odczekać chwilę

Dalej kiepsko, bo chcemy bez opóźnień przetwarzać zadania, jeśli są dostępne, i nie marnować prądu, jeśli nie są.

> Ale to tylko jeśli biblioteki faktycznie nie udostępniają
> jakichkolwiek mechanizmów sygnalizacji swoich potrzeb.

Dobry trop.
To w jaki sposób chciałbyś być poinformowany, że biblioteka ma potrzebę?

Przypominam, że mamy 3 biblioteki. Przyjmijmy wersję idealną, że wszystkie 3 będą mieć ten mechanizm. Jaki?

-- 
Maciej Sobczak * http://www.inspirel.com

[toc] | [prev] | [next] | [standalone]


#34014

FromMateusz Viste <mateusz@xyz.invalid>
Date2020-06-11 10:37 +0200
Message-ID<20200611103732.69e48f11@mateusz>
In reply to#34013
2020-06-10 o 14:19 -0700, Maciej Sobczak napisał:
> Jest gorzej. To nie muszą być sockety. Np. system QNX ma fajny
> mechanizm komunikacji IPC, który istnieje poza przestrzenią
> deskryptorów plików. A ktoś inny będzie się komunikował przez pamięć
> dzieloną.

Trzymajmy się założeń: była mowa o bibliotece "do http", innej "do
tweetera" i trzeciej "baza danych". Każda z nich raczej (?) opiera się
na socketach.

> No i nie możemy zakładać, że socket jest jeden, albo że ciągle ten
> sam, itd. Straszne komplikacje.

Jeśli jest ten sam to komplikacji nie ma - jeśli się urywa to
biblioteka zwraca błąd i trzeba zainicjalizować na nowo. Jeśli
natomiast socket się tworzy nowy przy każdym zawołaniu (np. sprawdzanie
tweetów via nową sesję ssl za każdym razem), to każde sprawdzenia
powinno być regularnie wywoływane przez program.

> dodatkowy argument, żeby czekać. Tak jest w YAMI4. Wtedy pętla
> użytkownika nie musi być busy - po prostu blokuje się, jak nie ma nic
> do roboty.

Po bardzo pobieżnym przejrzeniu rozumiem to tak, że inspirel oczekuje
że stworzysz swój własny wątek specjalnie dla wołania ich biblioteki:

 "All activity has to be driven by the application, which is supposed to
  'lease' one of its threads for doing the I/O work on behalf of the
  agent. This is achieved by calling the Do_Some_Work procedure in Ada
  or the do_some_work function in C++.

  The 'do some work' routine performs a single unit of work and
  returns to the caller. In a typical application it will be called in
  a tight loop."

W takiej sytuacji niewiele można zrobić. Patrz niżej.

> > Ale to tylko jeśli biblioteki faktycznie nie udostępniają
> > jakichkolwiek mechanizmów sygnalizacji swoich potrzeb.  
> 
> Dobry trop.
> To w jaki sposób chciałbyś być poinformowany, że biblioteka ma
> potrzebę?
> 
> Przypominam, że mamy 3 biblioteki. Przyjmijmy wersję idealną, że
> wszystkie 3 będą mieć ten mechanizm. Jaki?

Idealnie? No to chcę sam obsługiwać kanał danych (socket, IPC,
whatever), a bibliotekę będę wołał tylko po to, żeby te dane
obrobić/przetłumaczyć. Alternatywnie - niech biblioteka da dostęp do
socketów, wówczas wiem, że jak coś się zmieni na kablu to powinien
zawołać kogoś do obsługi. Ostatnia opcja: niech biblioteka da jakiś
swój blokujący "wait_for_event()", sama niech blokuje w sposób
eko-mądry i zależny od implementacji, a ja sobie ją wywołam w osobnym
wątku. 3 biblioteki = 3 wątki, da się przeżyć.

Mateusz

[toc] | [prev] | [next] | [standalone]


#34015

FromMaciej Sobczak <see.my.homepage@gmail.com>
Date2020-06-11 11:00 -0700
Message-ID<9386ac2d-2d1d-46db-8f52-250c1511dfebo@googlegroups.com>
In reply to#34014
> Trzymajmy się założeń: była mowa o bibliotece "do http", innej "do
> tweetera" i trzeciej "baza danych".

Nie. Była mowa o integracji kilku bibliotek event-based.
Przykłady dot. HTTP, bazy danych i Twittera to były *przykłady* do zobrazowania problemu a nie konkretne zadania do rozwiązania.
Właściwym problemem jest integracja bibliotek narzucających jakiś idiom czy wzorzec ich obsługi.

> Każda z nich raczej (?) opiera się
> na socketach.

Nie. W szczególności biblioteka do baz danych automatycznie dobierze metodę komunikacji zależnie od tego, gdzie jest baza. W szczególności, jeśli baza jest na tym samym komputerze, to istnieją sprawniejsze metody komunikacji, niż sockety.

Wyobraź sobie dla jeszcze szerszego spektrum, że jedna z tych bibliotek to zwykłe GUI, gdzie "gotowość" to event w kolejce, bo użytkownik coś kliknął.

Czyli tu nie chodzi o sockety. Tu chodzi o integrację bibliotek.

> > No i nie możemy zakładać, że socket jest jeden, albo że ciągle ten
> > sam, itd. Straszne komplikacje.
> 
> Jeśli jest ten sam to komplikacji nie ma - jeśli się urywa to
> biblioteka zwraca błąd i trzeba zainicjalizować na nowo. Jeśli
> natomiast socket się tworzy nowy przy każdym zawołaniu (np. sprawdzanie
> tweetów via nową sesję ssl za każdym razem), to każde sprawdzenia
> powinno być regularnie wywoływane przez program.

Nie na temat, ale dalej źle. Przykładowo, YAMI4 może mieć tysiące socketów. Pomijając drobny fakt, że select() nie nadaje się do obsługi tysięcy socketów, biblioteka stosuje algorytmy control-flow decydujące o tym, który kanał w ogóle albo w danym momencie zasługuje na obsługę. Czyli z faktu, że wśród tysięcy socketów kilkaset ma dane gotowe do odczytu wcale nie wynika, że to jest stan gotowości do wykonania zadania, bo akurat te sockety z gotowymi danymi nie muszą mieć "zielonego światła" na ruch komunikatów i może się okazać, że wtedy nadal jest "idle". O tym decyduje biblioteka.
Dlatego nie możesz się nastawiać na to, że będziesz sobie sam obserwował te sockety, bo i tak nie masz kontekstu do pełnej oceny sytuacji.

Co więcej, jest kompletnie bez sensu, żebyś duplikował ciężką pracę, którą biblioteka i tak robi w środku.

> > Przypominam, że mamy 3 biblioteki. Przyjmijmy wersję idealną, że
> > wszystkie 3 będą mieć ten mechanizm. Jaki?
> 
> Idealnie? No to chcę sam obsługiwać kanał danych (socket, IPC,
> whatever), a bibliotekę będę wołał tylko po to, żeby te dane
> obrobić/przetłumaczyć.

Już ustaliliśmy (powyżej), że nie.

> Ostatnia opcja: niech biblioteka da jakiś
> swój blokujący "wait_for_event()", sama niech blokuje w sposób
> eko-mądry i zależny od implementacji, a ja sobie ją wywołam w osobnym
> wątku. 3 biblioteki = 3 wątki, da się przeżyć.

Świetnie.
Doszedłeś w ten sposób do wniosku, że do obsługi *kilku* bibliotek event-based potrzebne są wątki. Albo wyjdą z biblioteki albo do niej wejdą. Ale będą potrzebne.

Głębsza analiza wygląda tak:
Pojęcie "idle" lub "nie ma zadania", itp. to pojęcia *lokalne*, zrozumiałe tylko w obrębie jednej biblioteki. Tzn. w bibliotece GUI to pojęcie oznacza, że user nic nie kliknął, w bibliotece komunikacyjnej że nie ma komunikatu, w bibliotece do baz danych że nie ma jeszcze odpowiedzi na wcześniejsze zapytanie, itd. To są stany *lokalne*.
Jeżeli program jest w całości oparty o rytm pracy *jednej* biblioteki (tak jak w prostym GUI opartym o zdarzenia z okna), to ten lokalny koncept jest też globalny, czyli dotyczy całego programu. Wtedy nie są potrzebne ani wątki, ani muteksy.

Ale jeśli mamy kilka takich bibliotek, każda ze swoim własnym konceptem "idle", to ich integracja jest problemem, bo globalnie "idle" oznacza, że *nikt* nie ma nic do roboty a tego stanu nie da się uwspólnić w jednym wątku, bez ciężkich kompromisów typu kręcenie się w pętli z odpytywaniem (nawet z jakimś mniej lub bardziej przemyślanym opóźnieniem).

Dlatego albo:
1. pozwolimy tym bibliotekom niezależnie informować o swoim bieżącym stanie przez callbacki wychodzące z tych bibliotek (w takim callbacku można np. odetkać główną pętlę czekającą na jakiejś fladze stopu) (co wymaga istnienia wątków w tych bibliotekach), albo
2. zrobimy sobie osobne wątki do kręcenia blokującymi pętlami dla każdej biblioteki osobno, albo
3. w ogóle schowamy ten koncept "idle" razem z pętlami zdarzeń i pozwolimy bibliotekom kręcić swoimi zdarzeniami samodzielnie (z własnych wątków).

Tak czy inaczej mamy wątki. I ich konsekwencje.
Ktoś ma pomysł na rozwiązanie tego problemu bez wątków?

-- 
Maciej Sobczak * http://www.inspirel.com

[toc] | [prev] | [next] | [standalone]


#34016

FromMateusz Viste <mateusz@xyz.invalid>
Date2020-06-11 21:58 +0200
Message-ID<20200611215852.33a1c421@mateusz>
In reply to#34015
2020-06-11 o 11:00 -0700, Maciej Sobczak napisał:
> > Trzymajmy się założeń: była mowa o bibliotece "do http", innej "do
> > tweetera" i trzeciej "baza danych".  
> 
> Nie. Była mowa o integracji kilku bibliotek event-based.
> Przykłady dot. HTTP, bazy danych i Twittera to były *przykłady* do
> zobrazowania problemu a nie konkretne zadania do rozwiązania.

No widzisz, ja nie zajmuję się akademickimi rozważaniami, staram się
rozwiązywać wyłącznie praktyczne problemy. Było trafniejszy przykład
dać.

> Nie. W szczególności biblioteka do baz danych automatycznie dobierze
> metodę komunikacji zależnie od tego, gdzie jest baza. W
> szczególności, jeśli baza jest na tym samym komputerze

Unix domain? Też socket.

> to istnieją sprawniejsze metody komunikacji, niż sockety.

"sprawniejsze" w tym kontekście jest niezwykle śmieszne. Nie słyszałem
jeszcze o tym, by komukolwiek udało się odciążyć serwer bazodanowy
poprzez zmianę kanału komunikacji na "sprawniejszy" (pomijam ew.
głupoty jak silne ssl po localhost). To po prostu nie ma żadnego
znaczenia. No ale rozumiem, że znów chodzi o to, że oczekiwałeś
złotego rozwiązania na ogólny problem, a ja tu włażę w kaloszach
i saperką. Idealista.

> Pomijając drobny fakt, że select() nie nadaje się do obsługi tysięcy
> socketów

Użyj poll(). Względnie epoll().

> Co więcej, jest kompletnie bez sensu, żebyś duplikował ciężką pracę,
> którą biblioteka i tak robi w środku.

To zależy od konkretnego przypadku. Ciężka praca polegająca na otwarciu
połączenia żeby sprawdzić tweetera nie jest tak znów ciężka. Przy
innych rzeczach może być inaczej.

> Doszedłeś w ten sposób do wniosku, że do obsługi *kilku* bibliotek
> event-based potrzebne są wątki. Albo wyjdą z biblioteki albo do niej
> wejdą. Ale będą potrzebne.

Przy założeniu, że chcesz quasi-natychmiastowy czas reakcji, że
biblioteka nie udostępnia socketa(ów), że nie pracujesz na
żadnych przerwaniach sprzętowych oraz że nie chcesz busy loop z
opóźnieniem (lub bez)... to tak. Wszystko zależy od założeń
projektowych.

> tego stanu nie da się uwspólnić w jednym wątku, bez ciężkich
> kompromisów typu kręcenie się w pętli z odpytywaniem (nawet z jakimś
> mniej lub bardziej przemyślanym opóźnieniem).

"ciężki kompromis"? Bez przesady. Tak działał m.in. Win 3.x. I w
praktyce bardzo fajnie mu wychodziło. Kwestia doboru timingu do
akceptowalnego poziomu latencji oraz możliwości buforowych tego, co
biblioteki mają obsłużyć. A jeśli ma być nowocześnie i szybko to
wątki. No ale ty chcesz uniwersalny lek na zło całego świata. :)

Mateusz

[toc] | [prev] | [next] | [standalone]


#34017

FromMaciej Sobczak <see.my.homepage@gmail.com>
Date2020-06-12 11:55 -0700
Message-ID<5ecf1d89-86e9-4b98-b92b-f90a1c9a739ao@googlegroups.com>
In reply to#34016
> > Nie. W szczególności biblioteka do baz danych automatycznie dobierze
> > metodę komunikacji zależnie od tego, gdzie jest baza. W
> > szczególności, jeśli baza jest na tym samym komputerze
> 
> Unix domain? Też socket.

https://www.ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0/com.ibm.admin.doc/ids_admin_0133.htm

No jednak nie socket.

> > to istnieją sprawniejsze metody komunikacji, niż sockety.
> 
> "sprawniejsze" w tym kontekście jest niezwykle śmieszne. Nie słyszałem
> jeszcze o tym, by komukolwiek udało się odciążyć serwer bazodanowy
> poprzez zmianę kanału komunikacji na "sprawniejszy"

https://www.ibm.com/support/knowledgecenter/SSGU8G_14.1.0/com.ibm.admin.doc/ids_admin_0343.htm

"The database server uses shared memory to [...] provide a fast communications channel for local client applications [...]."

> No ale rozumiem, że znów chodzi o to, że oczekiwałeś
> złotego rozwiązania na ogólny problem, a ja tu włażę w kaloszach
> i saperką.

Zapraszam również w kaloszach.

> > Pomijając drobny fakt, że select() nie nadaje się do obsługi tysięcy
> > socketów
> 
> Użyj poll(). Względnie epoll().

Ani poll() ani epoll() nie działają z pamięcią dzieloną, którą Twój klient używa do sprawnej komunikacji z bazą danych na tym samym komputerze.

> > Co więcej, jest kompletnie bez sensu, żebyś duplikował ciężką pracę,
> > którą biblioteka i tak robi w środku.
> 
> To zależy od konkretnego przypadku.

Tak. W podanym przeze mnie konkretnym przypadku jest to bez sensu.

> > Doszedłeś w ten sposób do wniosku, że do obsługi *kilku* bibliotek
> > event-based potrzebne są wątki.
> 
> Przy założeniu, że chcesz quasi-natychmiastowy czas reakcji, że
> biblioteka nie udostępnia socketa(ów), że nie pracujesz na
> żadnych przerwaniach sprzętowych oraz że nie chcesz busy loop z
> opóźnieniem (lub bez)... to tak. Wszystko zależy od założeń
> projektowych.

Właśnie takie mam założenia projektowe.

Bo można mieć też inne założenia projektowe - np. takie, że z założenia ma nie być wątków, niezależnie od ceny, którą trzeba będzie za ten brak wątków zapłacić. Wtedy oczywiście szukamy innych rozwiązań.

Ogólnie - minimalizujemy koszt.

> No ale ty chcesz uniwersalny lek na zło całego świata. :)

Nie. Dyskutujemy sobie tylko, a kontakt z innym punktem widzenia pozwala też lepiej zrozumieć swój własny.

-- 
Maciej Sobczak * http://www.inspirel.com

[toc] | [prev] | [next] | [standalone]


#34020

FromMateusz Viste <mateusz@xyz.invalid>
Date2020-06-13 09:33 +0200
Message-ID<20200613093325.6a641a6c@mateusz>
In reply to#34017
2020-06-12 o 11:55 -0700, Maciej Sobczak napisał:
> https://www.ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0/com.ibm.admin.doc/ids_admin_0133.htm

Heh, Informix :) Nie wiedziałem, że to jeszcze istnieje. Ostatnio
słyszałem o tym co najmniej 20 lat temu. Z ciekawości zapytam - bo nie
znam - dlaczego ktoś wolałby Informix zamiast takiego np. PostgreSQL?

> No jednak nie socket.

No nie, bo to nie unix domain o którym pisałem, tylko pamięć
współdzielona. Między liniami czytając (i nie wgłębiając się zanadto w
ich dokumentację) rozumiem, że IBM proponuje zwyczajne korzystanie z
wątków ("poll threads for shared memory connections").

> "The database server uses shared memory to [...] provide a fast
> communications channel for local client applications [...]."

No właśnie. Po co ktoś miałby taką gimnastykę wykonywać w ramach
komunikacji *z bazą danych* jest poza moim zasięgiem zrozumienia, ale
umiem sobie wyobrazić, że ktoś się uparł i tak chce - bo tak.

> > Przy założeniu, że chcesz quasi-natychmiastowy czas reakcji, że
> > biblioteka nie udostępnia socketa(ów), że nie pracujesz na
> > żadnych przerwaniach sprzętowych oraz że nie chcesz busy loop z
> > opóźnieniem (lub bez)... to tak. Wszystko zależy od założeń
> > projektowych.
> 
> Właśnie takie mam założenia projektowe.

Z podanych linków wnioskuję, że jesteś pośrednio lub bezpośrednio
klientem Informixa. Masz zatem pewnie dostęp do ichniego supportu
deweloperskiego - być może warto ich zapytać, co proponują przy takich
założeniach, bez użycia wątków? Ciekaw jestem odpowiedzi.

> Nie. Dyskutujemy sobie tylko, a kontakt z innym punktem widzenia
> pozwala też lepiej zrozumieć swój własny.

Ja prosty człowiek jestem, świat postrzegam w kategoriach bardzo
mechanicznych. To dotyczy również programowania. W omawianym
przykładzie mamy 3 pudełka, każde otwierane innym rodzajem klucza. W
tych pudełkach raz na jakiś czas pojawia się zawartość, którą należy
wyciągnąć żeby pudełko się nie zapchało. Pudełka są nieprzeźroczyste i
jedyną metodą sprawdzenia czy coś w nich jest, jest ich otwarcie za
pomocą specjalnego klucza. No to nie ma cudów: trzeba otwierać... I tu
do wyboru otwieranie/zamykanie sekwencyjnie w kółko jeden po drugim, lub
ew. postawienie przed każdym pudełkiem dedykowanego pracownika, który
przytrzymuje wieczko i czeka aż coś się pojawi. W mojej perspektywie
rzeczywistości nie ma innej drogi, no ale jeśli się mylę to chętnie się
dowiem.

Mateusz

[toc] | [prev] | [next] | [standalone]


#34021

FromMaciej Sobczak <see.my.homepage@gmail.com>
Date2020-06-13 12:52 -0700
Message-ID<618ccdb2-d697-42f3-bf3d-7c0bb9b6e4c8o@googlegroups.com>
In reply to#34020
> Heh, Informix :) Nie wiedziałem, że to jeszcze istnieje.

https://docs.oracle.com/database/timesten-18.1/TTOPR/client_server.htm#TTOPR182

"Using a shared memory segment provides better performance than TCP/IP communication."

To nie jest kwestia przestarzałego Informixa.

> Z ciekawości zapytam - bo nie
> znam - dlaczego ktoś wolałby Informix zamiast takiego np. PostgreSQL?

Bo komuś się tak opłaca. W jakimś sensie tego słowa.

[wracamy do pamięci dzielonej]
> No właśnie. Po co ktoś miałby taką gimnastykę wykonywać w ramach
> komunikacji *z bazą danych* jest poza moim zasięgiem zrozumienia, ale
> umiem sobie wyobrazić, że ktoś się uparł i tak chce - bo tak.

Nie. Tak jest naprawdę szybciej. Bo najszybsza komunikacja jest wtedy, gdy jej nie ma.
W szczególności, jeśli dane w bazie istnieją w postaci jakiejś struktury, to tej struktury nawet nie trzeba serializować - wystarczy ją klientowi pokazać. Pakowanie danych do strumienia, po to żeby inny proces na tym samym komputerze te same dane sobie rozpakował, jest po prostu marnowaniem prądu.

> Z podanych linków wnioskuję, że jesteś pośrednio lub bezpośrednio
> klientem Informixa.

Różne rzeczy widziałem na tej grupie w ciągu ostatnich dni, ale tym zrobiłeś mi weekend. :-)

Nie mam o tym bladego pojęcia.
Do szukania linków używam Google'a - i też nie jestem ich klientem (chociaż w tym przypadku pewnie jestem nawet jeśli o tym nie wiem).

> Ja prosty człowiek jestem, świat postrzegam w kategoriach bardzo
> mechanicznych. To dotyczy również programowania. W omawianym
> przykładzie mamy 3 pudełka, każde otwierane innym rodzajem klucza. W
> tych pudełkach raz na jakiś czas pojawia się zawartość, którą należy
> wyciągnąć żeby pudełko się nie zapchało.

I to też sobie wczoraj uświadomiłem, że jakoś niechcący wpadliśmy w narrację, że z tych gniazdek (albo nie-gniazdek) się tylko czyta.

Ale przecież nawet ta biblioteka do Twittera nie musi tylko czytać (albo w ogóle nie musi czytać), może natomiast pisać. Znaczy - wysyłać tweety. Np. co godzinę. Są nawet takie konta na Twitterze, gdzie jakiś automat coś pluje co jakiś czas.
No więc mamy gniazdo, powiedzmy nawet że się do niego dobraliśmy łamiąc zasady enkapsulacji i robimy na nim select() (czy tam inny poll) i dowiadujemy, się, że gniazdo jest gotowe do pisania. Hura!
I co z tego wynika, że jest gotowe do pisania? Ano nic nie wynika. Bo to biblioteka decyduje, czy ma coś do pisania, a nie użytkownik, który dobrał się jej do gniazda.
Więc gotowość gniazda wcale nie świadczy o tym, że jest jakiś inkrement pracy do wykonania.

> I tu
> do wyboru otwieranie/zamykanie sekwencyjnie w kółko jeden po drugim, lub
> ew. postawienie przed każdym pudełkiem dedykowanego pracownika, który
> przytrzymuje wieczko i czeka aż coś się pojawi. W mojej perspektywie
> rzeczywistości nie ma innej drogi,

Też się do tego wniosku skłaniam.

-- 
Maciej Sobczak * http://www.inspirel.com

[toc] | [prev] | [next] | [standalone]


#34022

FromMateusz Viste <mateusz@xyz.invalid>
Date2020-06-14 13:55 +0200
Message-ID<20200614135509.1856260f@mateusz>
In reply to#34021
2020-06-13 o 12:52 -0700, Maciej Sobczak napisał:
> "Using a shared memory segment provides better performance than
> TCP/IP communication."

Jasne, ale już pisałem - bez sensu. To jak jeżdżenie z wyłączonymi
światłami w samochodzie dla oszczędzania paliwa, mając V16 turbo pod
maską.

> Pakowanie danych do strumienia, po to żeby inny proces na tym samym
> komputerze te same dane sobie rozpakował, jest po prostu marnowaniem
> prądu.

Idąc tym tropem, to pisanie w C jest marnowaniem prądu - powinniśmy
trzaskać wyłącznie goły ASM. :)
No i baza danych SQL to też poroniony pomysł, przecież te wszelkie
SELECTy, JOINy itd trzeba przeanalizować, zrozumieć, przetworzyć...
Ileż to prądu! Użycie socketa w tym wszystkim to pikuś.

> Różne rzeczy widziałem na tej grupie w ciągu ostatnich dni, ale tym
> zrobiłeś mi weekend. :-)
> 
> Nie mam o tym bladego pojęcia.
> Do szukania linków używam Google'a - i też nie jestem ich klientem
> (chociaż w tym przypadku pewnie jestem nawet jeśli o tym nie wiem).

Entuzjastycznie założyłem, że podajesz w końcu jakiś prawdziwy
przypadek, a nie że przeszukałeś internet żeby na siłę znaleźć "chcę
wysyłać selecty via shmem". Faktycznie, mój błąd.

Mateusz

[toc] | [prev] | [next] | [standalone]


#34023

FromMaciej Sobczak <see.my.homepage@gmail.com>
Date2020-06-14 11:52 -0700
Message-ID<10cfa09f-7d5a-43c3-8798-16fb085044c6o@googlegroups.com>
In reply to#34022
> > "Using a shared memory segment provides better performance than
> > TCP/IP communication."
> 
> Jasne, ale już pisałem - bez sensu. To jak jeżdżenie z wyłączonymi
> światłami w samochodzie dla oszczędzania paliwa, mając V16 turbo pod
> maską.

A skąd to porównanie?
Jeżeli aplikacja potrzebuje odebrać z bazy np. 1GB danych, to zamiast przesyłać te dane przez gniazda, lepiej ich w ogóle nie przesyłać.

> Idąc tym tropem, to pisanie w C jest marnowaniem prądu - powinniśmy
> trzaskać wyłącznie goły ASM. :)

Niektórzy swoje programy w C kompilują.

> No i baza danych SQL to też poroniony pomysł, przecież te wszelkie
> SELECTy, JOINy itd trzeba przeanalizować, zrozumieć, przetworzyć...
> Ileż to prądu! Użycie socketa w tym wszystkim to pikuś.

Ale masz na to jakieś dane? Liczby?

Jeżeli robisz proste zapytanie na dużą ilość danych, to jakie będą proporcje?

> Entuzjastycznie założyłem, że podajesz w końcu jakiś prawdziwy
> przypadek,

Prawdziwy przypadek to YAMI4, wymieniony już przeze mnie w tej dyskusji. Jednym z jego protokołów jest "qnx://", który w ogóle nie opiera się na gniazdach, a jest, razem z innymi protokołami, objęty obsługą w jednej funkcji do_some_work().

> a nie że przeszukałeś internet żeby na siłę znaleźć

Ja mam wrażenie, że w ciągu ostatnich paru dni najwięcej prądu na tej grupie poszło dzięki grupowiczom, którzy na siłę szukają metody, żeby być "przeciw".
A jeśli szukam czegoś w internecie, to przykładów potwierdzających moje argumenty - z nadzieją, że te argumenty stają się wtedy bardziej obiektywne.

-- 
Maciej Sobczak * http://www.inspirel.com

[toc] | [prev] | [standalone]


Back to top | Article view | pl.comp.programming


csiph-web