@@ -169,70 +169,84 @@ public synchronized void start() {
169169 this .latch = new CountDownLatch (1 );
170170
171171 CountDownLatch startingLatch = new CountDownLatch (1 );
172- this .future = executorToUse .submit (() -> {
173- try {
174- while (isActive ()) {
175- try {
176- PgConnection conn = this .connectionSupplier .get ();
177- try (Statement stmt = conn .createStatement ()) {
178- stmt .execute ("LISTEN " + this .tablePrefix .toLowerCase () + "channel_message_notify" );
172+ this .future = executorToUse .submit (() -> doStart (startingLatch ));
173+
174+ try {
175+ if (!startingLatch .await (5 , TimeUnit .SECONDS )) {
176+ throw new IllegalStateException ("Failed to start " + this );
177+ }
178+ }
179+ catch (InterruptedException ex ) {
180+ Thread .currentThread ().interrupt ();
181+ throw new IllegalStateException ("Failed to start " + this , ex );
182+ }
183+ }
184+
185+ private void doStart (CountDownLatch startingLatch ) {
186+ try {
187+ while (isActive ()) {
188+ try {
189+ PgConnection conn = this .connectionSupplier .get ();
190+ try (Statement stmt = conn .createStatement ()) {
191+ stmt .execute ("LISTEN " + this .tablePrefix .toLowerCase () + "channel_message_notify" );
192+ }
193+ catch (Exception ex ) {
194+ try {
195+ conn .close ();
196+ }
197+ catch (Exception suppressed ) {
198+ ex .addSuppressed (suppressed );
179199 }
180- catch (Exception ex ) {
181- try {
182- conn .close ();
200+ throw ex ;
201+ }
202+ this .subscriptionsMap .values ()
203+ .forEach (subscriptions -> subscriptions .forEach (Subscription ::notifyUpdate ));
204+ try {
205+ this .connection = conn ;
206+ while (isActive ()) {
207+ startingLatch .countDown ();
208+
209+ PGNotification [] notifications = conn .getNotifications ((int ) this .notificationTimeout .toMillis ());
210+ // Unfortunately, there is no good way of interrupting a notification
211+ // poll but by closing its connection.
212+ if (!isActive ()) {
213+ return ;
183214 }
184- catch (Exception suppressed ) {
185- ex .addSuppressed (suppressed );
215+ if ((notifications == null || notifications .length == 0 ) && !conn .isValid (1 )) {
216+ //We did not receive any notifications within the timeout period.
217+ //If the connection is still valid, we will continue polling
218+ //Otherwise, we will close the connection and re-establish it.
219+ break ;
186220 }
187- throw ex ;
188- }
189- this .subscriptionsMap .values ()
190- .forEach (subscriptions -> subscriptions .forEach (Subscription ::notifyUpdate ));
191- try {
192- this .connection = conn ;
193- while (isActive ()) {
194- startingLatch .countDown ();
195-
196- PGNotification [] notifications = conn .getNotifications ((int ) this .notificationTimeout .toMillis ());
197- // Unfortunately, there is no good way of interrupting a notification
198- // poll but by closing its connection.
199- if (!isActive ()) {
200- return ;
221+ for (PGNotification notification : notifications ) {
222+ String parameter = notification .getParameter ();
223+ Set <Subscription > subscriptions = this .subscriptionsMap .get (parameter );
224+ if (subscriptions == null ) {
225+ continue ;
201226 }
202- if (notifications == null || notifications .length == 0 ) {
203- //We did not receive any notifications within the timeout period.
204- //We will close the connection and re-establish it.
205- break ;
206- }
207- for (PGNotification notification : notifications ) {
208- String parameter = notification .getParameter ();
209- Set <Subscription > subscriptions = this .subscriptionsMap .get (parameter );
210- if (subscriptions == null ) {
211- continue ;
212- }
213- for (Subscription subscription : subscriptions ) {
214- subscription .notifyUpdate ();
215- }
227+ for (Subscription subscription : subscriptions ) {
228+ subscription .notifyUpdate ();
216229 }
217230 }
218- }
219- finally {
220- conn .close ();
231+
221232 }
222233 }
223- catch (Exception e ) {
224- // The getNotifications method does not throw a meaningful message on interruption.
225- // Therefore, we do not log an error, unless it occurred while active.
226- if (isActive ()) {
227- LOGGER .error (e , "Failed to poll notifications from Postgres database" );
228- }
234+ finally {
235+ conn .close ();
236+ }
237+ }
238+ catch (Exception e ) {
239+ // The getNotifications method does not throw a meaningful message on interruption.
240+ // Therefore, we do not log an error, unless it occurred while active.
241+ if (isActive ()) {
242+ LOGGER .error (e , "Failed to poll notifications from Postgres database" );
229243 }
230244 }
231245 }
232- finally {
233- this . latch . countDown ();
234- }
235- });
246+ }
247+ finally {
248+ this . latch . countDown ();
249+ }
236250
237251 try {
238252 if (!startingLatch .await (5 , TimeUnit .SECONDS )) {
0 commit comments