Moja aplikacja internetowa Python ma kilka połączeń zarejestrowanych na tym samym serwerze MongoDb, ale 3 różne bazy danych. Aplikacja prowadzona jest pod 4 pracownikami Gunicorn.Blokuj, dopóki nie zostanie skonfigurowana nowa konfiguracja zestawu replik
Używam zestawu replik.
Gdy podstawowy jest wyłączony, prąd kwerenda nie powiedzie i odświeżania jest zaplanowane w MongoReplicaSetClient (2.8, ale myślę, że w 3.2 jest taka sama). Następne zapytanie może się powieść, jeśli do czasu zostanie wybrany nowy element główny, a program MonitorThread otrzyma informacje o aktualizacji połączenia klienta.
Ale odświeżenie dotyczy tylko tego klienta. Inni klienci podłączeni do tego samego serwera MongoDB nie mają wpływu - ta sama historia dzieje się z każdym. Oznacza to, że jeśli każdy pracownik jest podłączony do 3 baz danych na tym samym serwerze MongoDB i powtarzam to samo żądanie HTTP, które używa wszystkich 3 baz danych, gdy podstawowy nie powiedzie się, aktualizację wszystkich podłączonych klientów zajmuje nieokreślony czas. Jeśli każde żądanie HTTP przechodzi w trybie round-robin do każdego pracownika na 4, potrzebujemy 12 żądań aktualizacji każdego klienta Mongo. Ale w rzeczywistości prośby nie idą dookoła.
Patrząc na kod PyMongo MongoReplicaSetClient._send_message_with_response
widzę, że gdy podstawowy jest w dół, self.disconnect
nazywa który nazywa self.__schedule_refresh
. Ta metoda ma argument sync
, który umożliwia "blokowanie do zakończenia odświeżania".
Mój pomysł to złapać wyjątek AutoReconnect
i zadzwonić pod numer __schedule_refresh(sync=True)
na wszystkich klientach, którzy są połączeni z uszkodzonym podstawowym i blokowym, dopóki nie zostanie skonfigurowana nowa konfiguracja zestawu replik. Więc żądania HTTP nie będą przetwarzane (co daje 500) dopóki baza danych nie będzie w porządku.
Ale __schedule_refresh
to prywatna metoda. Również nie wiem, czy wywołanie go sekwencyjnie na wszystkich klientach będzie szybkie - wygląda MonitorThread
wykonuje swoją pracę w odstępach czasu.
A może mógłbym użyć MongoReplicaSetClient.refresh
.
Co sądzisz o tym pomyśle? Czy ma wady?
Pomożesz mi we wdrożeniu?