Hi Hackers,
Attached is the workaround patch to set the default connection timeout to
30 seconds instead of the current value of infinite - 0, zero. The input is
present in the server properties dialogs advanced tab. The workaround
applies to the RM4724 as well.
The permanent solution would be to expand the nodes asynchronously -
https://redmine.postgresql.org/issues/4933
Also fixed a bug where sql editor is not closing if the server is
disconnected in between.
Kindly review.
--
Thanks and Regards,
Aditya Toshniwal
Sr. Software Engineer | EnterpriseDB India | Pune
"Don't Complain about Heat, Plant a TREE"
diff --git a/web/migrations/versions/aff1436e3c8c_.py b/web/migrations/versions/aff1436e3c8c_.py
new file mode 100644
index 000000000..b5952418b
--- /dev/null
+++ b/web/migrations/versions/aff1436e3c8c_.py
@@ -0,0 +1,27 @@
+
+""" Update the default timeout to 30 seconds instead on 0.
+0 indicates wait indefinitely which causes trouble when network connection
+to server is lost.
+
+Revision ID: aff1436e3c8c
+Revises: a77a0932a568
+Create Date: 2019-10-28 12:47:36.828709
+
+"""
+from pgadmin.model import db
+
+# revision identifiers, used by Alembic.
+revision = 'aff1436e3c8c'
+down_revision = 'a77a0932a568'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ db.engine.execute(
+ 'UPDATE server SET connect_timeout=30 WHERE connect_timeout=0 OR connect_timeout IS NULL'
+ )
+
+
+def downgrade():
+ pass
diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py
index dc39a1393..72f9e11a8 100644
--- a/web/pgadmin/browser/server_groups/servers/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/__init__.py
@@ -28,6 +28,7 @@ from pgadmin.model import db, Server, ServerGroup, User
from pgadmin.utils.driver import get_driver
from pgadmin.utils.master_password import get_crypt_key
from pgadmin.utils.exception import CryptKeyMissing
+from psycopg2 import OperationalError
def has_any(data, keys):
@@ -128,12 +129,20 @@ class ServerModule(sg.ServerGroupPluginModule):
except CryptKeyMissing:
# show the nodes at least even if not able to connect.
pass
+ except OperationalError as e:
+ current_app.logger.exception(e)
+ connected = False
in_recovery = None
wal_paused = None
if connected:
- in_recovery, wal_paused = recovery_state(conn, manager.version)
+ try:
+ in_recovery, wal_paused = recovery_state(conn, manager.version)
+ except OperationalError as e:
+ current_app.logger.exception(e)
+ connected = False
+
yield self.generate_browser_node(
"%d" % (server.id),
gid,
diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js
index 99fed949e..99297d4da 100644
--- a/web/pgadmin/browser/server_groups/servers/static/js/server.js
+++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js
@@ -732,7 +732,7 @@ define('pgadmin.node.server', [
tunnel_password: undefined,
tunnel_authentication: 0,
save_tunnel_password: false,
- connect_timeout: 0,
+ connect_timeout: 30,
},
// Default values!
initialize: function(attrs, args) {
diff --git a/web/pgadmin/model/__init__.py b/web/pgadmin/model/__init__.py
index 629e98f37..b22868fbb 100644
--- a/web/pgadmin/model/__init__.py
+++ b/web/pgadmin/model/__init__.py
@@ -29,7 +29,7 @@ from flask_sqlalchemy import SQLAlchemy
#
##########################################################################
-SCHEMA_VERSION = 23
+SCHEMA_VERSION = 24
##########################################################################
#
diff --git a/web/pgadmin/static/js/sqleditor/execute_query.js b/web/pgadmin/static/js/sqleditor/execute_query.js
index f714c2b50..63ad7721b 100644
--- a/web/pgadmin/static/js/sqleditor/execute_query.js
+++ b/web/pgadmin/static/js/sqleditor/execute_query.js
@@ -12,6 +12,7 @@ import $ from 'jquery';
import url_for from '../url_for';
import axios from 'axios';
import * as httpErrorHandler from './query_tool_http_error_handler';
+import * as queryTxnStatus from 'sources/sqleditor/query_txn_status_constants';
class LoadingScreen {
constructor(sqlEditor) {
@@ -83,7 +84,8 @@ class ExecuteQuery {
self.loadingScreen.hide();
self.enableSQLEditorButtons();
// Enable/Disable commit and rollback button.
- if (result.data.data.transaction_status == 2 || result.data.data.transaction_status == 3) {
+ if (result.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INTRANS
+ || result.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR) {
self.enableTransactionButtons();
} else {
self.disableTransactionButtons();
@@ -123,7 +125,8 @@ class ExecuteQuery {
self.updateSqlEditorLastTransactionStatus(httpMessage.data.data.transaction_status);
// Enable/Disable commit and rollback button.
- if (httpMessage.data.data.transaction_status == 2 || httpMessage.data.data.transaction_status == 3) {
+ if (httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INTRANS
+ || httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR) {
self.enableTransactionButtons();
} else {
self.disableTransactionButtons();
@@ -131,7 +134,7 @@ class ExecuteQuery {
if (ExecuteQuery.isQueryFinished(httpMessage)) {
if (this.sqlServerObject.close_on_idle_transaction &&
- httpMessage.data.data.transaction_status == 0)
+ httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_IDLE)
this.sqlServerObject.check_needed_confirmations_before_closing_panel();
self.loadingScreen.setMessage('Loading data from the database server and rendering...');
diff --git a/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js b/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js
new file mode 100644
index 000000000..075264296
--- /dev/null
+++ b/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js
@@ -0,0 +1,11 @@
+/* psycopg2 transaction status constants
+ * http://initd.org/psycopg/docs/extensions.html#transaction-status-constants
+ */
+
+module.exports = {
+ TRANSACTION_STATUS_IDLE: 0,
+ TRANSACTION_STATUS_ACTIVE: 1,
+ TRANSACTION_STATUS_INTRANS: 2,
+ TRANSACTION_STATUS_INERROR: 3,
+ TRANSACTION_STATUS_UNKNOWN: 5,
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
index 70d4bd348..5512382d4 100644
--- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
@@ -36,6 +36,7 @@ define('tools.querytool', [
'sources/sqleditor/calculate_query_run_time',
'sources/sqleditor/call_render_after_poll',
'sources/sqleditor/query_tool_preferences',
+ 'sources/sqleditor/query_txn_status_constants',
'sources/csrf',
'tools/datagrid/static/js/datagrid_panel_title',
'sources/window',
@@ -52,7 +53,7 @@ define('tools.querytool', [
XCellSelectionModel, setStagedRows, SqlEditorUtils, ExecuteQuery, httpErrorHandler, FilterHandler,
GeometryViewer, historyColl, queryHist, querySources,
keyboardShortcuts, queryToolActions, queryToolNotifications, Datagrid,
- modifyAnimation, calculateQueryRunTime, callRenderAfterPoll, queryToolPref, csrfToken, panelTitleFunc,
+ modifyAnimation, calculateQueryRunTime, callRenderAfterPoll, queryToolPref, queryTxnStatus, csrfToken, panelTitleFunc,
pgWindow) {
/* Return back, this has been called more than once */
if (pgAdmin.SqlEditor)
@@ -4178,8 +4179,9 @@ define('tools.querytool', [
self.unsaved_changes_user_confirmation(msg, false);
} // If a transaction is currently ongoing
else if (self.preferences.prompt_commit_transaction
- && self.last_transaction_status > 0) { // 0 -> idle (no transaction)
- var is_commit_disabled = self.last_transaction_status == 3; // 3 -> Failed transaction
+ && (self.last_transaction_status === queryTxnStatus.TRANSACTION_STATUS_INTRANS
+ || self.last_transaction_status === queryTxnStatus.TRANSACTION_STATUS_INERROR)) {
+ var is_commit_disabled = self.last_transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR;
self.uncommitted_transaction_user_confirmation(is_commit_disabled);
}
else {