bool setting_vars:1; /* server: setting client vars */
bool exec_on_connect:1; /* server: executing connect_query */
bool resetting:1; /* server: executing reset query from auth login; don't release on flush */
+ bool copy_mode:1; /* server: in copy stream, ignores any Sync packets */
bool wait_for_welcome:1;/* client: no server yet in pool, cannot send welcome msg */
bool wait_for_user_conn:1;/* client: waiting for auth_conn server connection */
bool wait_sslchar:1; /* server: waiting for ssl response: S/N */
+ int expect_rfq_count; /* client: count of ReadyForQuery packets client should see */
+
usec_t connect_time; /* when connection was made */
usec_t request_time; /* last activity time */
usec_t query_start; /* query start moment */
} else if (state == 'T' || state == 'E') {
idle_tx = true;
}
+
+ if (client && !server->setting_vars) {
+ if (client->expect_rfq_count > 0) {
+ client->expect_rfq_count--;
+ } else if (server->state == SV_ACTIVE) {
+ slog_debug(client, "unexpected ReadyForQuery - expect_rfq_count=%d", client->expect_rfq_count);
+ }
+ }
break;
case 'S': /* ParameterStatus */
disconnect_server(server, true, "invalid server parameter");
return false;
}
+ case 'C': /* CommandComplete */
+
+ /* ErrorResponse and CommandComplete show end of copy mode */
+ if (server->copy_mode) {
+ server->copy_mode = false;
+
+ /* it's impossible to track sync count over copy */
+ if (client)
+ client->expect_rfq_count = 0;
+ }
+ break;
case 'N': /* NoticeResponse */
break;
ready = server->ready;
break;
+ /* copy mode */
+ case 'G': /* CopyInResponse */
+ case 'H': /* CopyOutResponse */
+ server->copy_mode = true;
+ break;
/* chat packets */
case '2': /* BindComplete */
case '3': /* CloseComplete */
case 'I': /* EmptyQueryResponse == CommandComplete */
case 'V': /* FunctionCallResponse */
case 'n': /* NoData */
- case 'G': /* CopyInResponse */
- case 'H': /* CopyOutResponse */
case '1': /* ParseComplete */
case 's': /* PortalSuspended */
- case 'C': /* CommandComplete */
/* data packets, there will be more coming */
case 'd': /* CopyData(F/B) */
break;
}
- if (pool_pool_mode(pool) != POOL_SESSION || server->state == SV_TESTED || server->resetting) {
+ if (pool_pool_mode(pool) != POOL_SESSION || server->state == SV_TESTED || server->resetting) {
server->resetting = false;
switch (server->state) {
case SV_ACTIVE:
case SV_TESTED:
+ /* keep link if client expects more Syncs */
+ if (server->link) {
+ if (server->link->expect_rfq_count > 0)
+ break;
+ }
+
/* retval does not matter here */
release_server(server);
break;