@@ -169,70 +169,84 @@ public synchronized void start() {
169
169
this .latch = new CountDownLatch (1 );
170
170
171
171
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 );
179
199
}
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 ;
183
214
}
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 ;
186
220
}
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 ;
201
226
}
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 ();
216
229
}
217
230
}
218
- }
219
- finally {
220
- conn .close ();
231
+
221
232
}
222
233
}
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" );
229
243
}
230
244
}
231
245
}
232
- finally {
233
- this . latch . countDown ();
234
- }
235
- });
246
+ }
247
+ finally {
248
+ this . latch . countDown ();
249
+ }
236
250
237
251
try {
238
252
if (!startingLatch .await (5 , TimeUnit .SECONDS )) {
0 commit comments