IDEMPIERE-4653 Improve timeout handling of window tab (#534)

* IDEMPIERE-4653 Improve timeout handling of window tab

* IDEMPIERE-4653 Improve timeout handling of window tab

Fix error with find and refresh.
This commit is contained in:
hengsin 2021-01-20 20:27:58 +08:00 committed by GitHub
parent cdb21c0698
commit e1ba21360f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 123 additions and 22 deletions

View File

@ -0,0 +1,10 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Jan 19, 2021, 1:34:10 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','The window tab took too long to return results.',0,0,'Y',TO_DATE('2021-01-19 13:34:09','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-01-19 13:34:09','YYYY-MM-DD HH24:MI:SS'),100,200659,'GridTabLoadTimeoutError','D','f016a5f8-3783-4640-b713-8f0e1b4d3bb6')
;
SELECT register_migration_script('202101190630_IDEMPIERE-4653.sql') FROM dual
;

View File

@ -0,0 +1,7 @@
-- Jan 19, 2021, 1:34:10 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','The window tab took too long to return results.',0,0,'Y',TO_TIMESTAMP('2021-01-19 13:34:09','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-01-19 13:34:09','YYYY-MM-DD HH24:MI:SS'),100,200659,'GridTabLoadTimeoutError','D','f016a5f8-3783-4640-b713-8f0e1b4d3bb6')
;
SELECT register_migration_script('202101190630_IDEMPIERE-4653.sql') FROM dual
;

View File

@ -199,9 +199,18 @@ public class DBException extends AdempiereException
* @param e
*/
public static boolean isTimeout(Exception e) {
if (DB.isPostgreSQL())
return isSQLState(e, "57014");
return isErrorCode(e, 1013);
SQLException se = null;
if (e instanceof SQLException) {
se = (SQLException) e;
} else if (e.getCause() != null && e.getCause() instanceof SQLException) {
se = (SQLException) e.getCause();
}
if (se != null) {
return DB.getDatabase().isQueryTimeout(se);
} else {
return false;
}
}
/**

View File

@ -112,7 +112,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
/**
*
*/
private static final long serialVersionUID = 8443012394354164942L;
private static final long serialVersionUID = 5086068543834849233L;
public static final String DEFAULT_STATUS_MESSAGE = "NavigateOrUpdate";
@ -3469,4 +3469,12 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
return max > 0 && noRecords > max;
} // isQueryMax
/***
* reset to empty
*/
public void reset() {
m_mTable.reset();
setCurrentRow(0, true);
}
} // GridTab

View File

@ -49,7 +49,6 @@ import java.util.logging.Level;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DBException;
import org.adempiere.util.ServerContext;
import org.compiere.Adempiere;
@ -104,7 +103,11 @@ public class GridTable extends AbstractTableModel
/**
*
*/
private static final long serialVersionUID = -3190218965990521698L;
private static final long serialVersionUID = -1869219003783467319L;
public static final int DEFAULT_GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS = 30;
public static final String LOAD_TIMEOUT_ERROR_MESSAGE = "GridTabLoadTimeoutError";
public static final String DATA_REFRESH_MESSAGE = "Refreshed";
public static final String DATA_UPDATE_COPIED_MESSAGE = "UpdateCopied";
@ -1087,7 +1090,7 @@ public class GridTable extends AbstractTableModel
// need to wait for data read into buffer
int loops = 0;
//wait for [timeout] seconds
int timeout = MSysConfig.getIntValue(MSysConfig.GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS, 30, Env.getAD_Client_ID(Env.getCtx()));
int timeout = MSysConfig.getIntValue(MSysConfig.GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS, DEFAULT_GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS, Env.getAD_Client_ID(Env.getCtx()));
while (row >= m_sort.size() && m_loaderFuture != null && !m_loaderFuture.isDone() && loops < timeout)
{
if (log.isLoggable(Level.FINE)) log.fine("Waiting for loader row=" + row + ", size=" + m_sort.size());
@ -1107,7 +1110,9 @@ public class GridTable extends AbstractTableModel
}
if (row >= m_sort.size()) {
log.warning("Reached " + timeout + " seconds timeout loading row " + (row+1) + " for SQL=" + m_SQL);
throw new IllegalStateException("Timeout loading row " + (row+1));
//adjust row count
m_rowCount = m_sort.size();
throw new DBException("GridTabLoadTimeoutError");
}
}
@ -3550,18 +3555,16 @@ public class GridTable extends AbstractTableModel
{
pstmt = DB.prepareStatement(m_SQL_Count, null);
setParameter (pstmt, true);
int timeout = MSysConfig.getIntValue(MSysConfig.GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS, DEFAULT_GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS, Env.getAD_Client_ID(Env.getCtx()));
if (timeout > 0)
pstmt.setQueryTimeout(timeout);
rs = pstmt.executeQuery();
if (rs.next())
rows = rs.getInt(1);
}
catch (SQLException e0)
{
// Zoom Query may have invalid where clause
if (DBException.isInvalidIdentifierError(e0))
log.warning("Count - " + e0.getLocalizedMessage() + "\nSQL=" + m_SQL_Count);
else
throw new AdempiereException(e0);
return 0;
throw new DBException(e0);
}
finally
{
@ -3602,6 +3605,9 @@ public class GridTable extends AbstractTableModel
if (m_virtual)
m_pstmt.setFetchSize(100);
setParameter (m_pstmt, false);
int timeout = MSysConfig.getIntValue(MSysConfig.GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS, DEFAULT_GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS, Env.getAD_Client_ID(Env.getCtx()));
if (timeout > 0)
m_pstmt.setQueryTimeout(timeout);
m_rs = m_pstmt.executeQuery();
}
catch (SQLException e)
@ -4042,4 +4048,25 @@ public class GridTable extends AbstractTableModel
{
return m_rowChanged;
}
/**
* reset to empty
*/
public void reset()
{
if (m_buffer != null)
m_buffer.clear();
m_changed = false;
m_rowChanged = -1;
if (m_sort != null)
m_sort.clear();
if (m_virtualBuffer != null)
m_virtualBuffer.clear();
m_rowCount = 0;
m_rowData = null;
m_oldValue = null;
m_inserting = false;
m_lastSortColumnIndex = -1;
m_lastSortedAscending = false;
}
}

View File

@ -29,6 +29,7 @@ import java.util.logging.Level;
import org.adempiere.base.Core;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DBException;
import org.adempiere.util.Callback;
import org.adempiere.webui.AdempiereIdGenerator;
import org.adempiere.webui.AdempiereWebUI;
@ -1161,9 +1162,23 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer
public void query (boolean onlyCurrentRows, int onlyCurrentDays, int maxRows)
{
boolean open = gridTab.isOpen();
gridTab.query(onlyCurrentRows, onlyCurrentDays, maxRows);
if (listPanel.isVisible() && !open)
gridTab.getTableModel().fireTableDataChanged();
try
{
gridTab.query(onlyCurrentRows, onlyCurrentDays, maxRows);
if (listPanel.isVisible() && !open)
gridTab.getTableModel().fireTableDataChanged();
}
catch (Exception e)
{
if (DBException.isTimeout(e))
{
FDialog.error(windowNo, GridTable.LOAD_TIMEOUT_ERROR_MESSAGE);
}
else
{
FDialog.error(windowNo, e.getMessage());
}
}
}
/**

View File

@ -32,6 +32,7 @@ import java.util.Properties;
import java.util.TreeMap;
import java.util.logging.Level;
import org.adempiere.exceptions.DBException;
import org.adempiere.util.Callback;
import org.adempiere.webui.AdempiereIdGenerator;
import org.adempiere.webui.AdempiereWebUI;
@ -1922,7 +1923,18 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
protected void doOnRefresh(final boolean fireEvent) {
IADTabpanel headerTab = adTabbox.getSelectedTabpanel();
IADTabpanel detailTab = adTabbox.getSelectedDetailADTabpanel();
adTabbox.getSelectedGridTab().dataRefreshAll(fireEvent, true);
try {
adTabbox.getSelectedGridTab().dataRefreshAll(fireEvent, true);
} catch (Exception e) {
if (DBException.isTimeout(e)) {
FDialog.error(getWindowNo(), "GridTabLoadTimeoutError");
} else {
FDialog.error(getWindowNo(), "Error", e.getMessage());
}
adTabbox.getSelectedGridTab().reset();
return;
}
adTabbox.getSelectedGridTab().refreshParentTabs();
headerTab.dynamicDisplay(0);
if (detailTab != null)

View File

@ -80,6 +80,7 @@ import org.adempiere.webui.util.ZKUpdateUtil;
import org.compiere.model.GridField;
import org.compiere.model.GridFieldVO;
import org.compiere.model.GridTab;
import org.compiere.model.GridTable;
import org.compiere.model.Lookup;
import org.compiere.model.MColumn;
import org.compiere.model.MLookup;
@ -88,6 +89,7 @@ import org.compiere.model.MLookupInfo;
import org.compiere.model.MProduct;
import org.compiere.model.MQuery;
import org.compiere.model.MRole;
import org.compiere.model.MSysConfig;
import org.compiere.model.MTable;
import org.compiere.model.MUserQuery;
import org.compiere.model.SystemIDs;
@ -2471,20 +2473,31 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
if (log.isLoggable(Level.INFO))
Env.setContext(Env.getCtx(), m_targetWindowNo, TABNO, GridTab.CTX_FindSQL, finalSQL);
// Execute Qusery
// Execute Query
int timeout = MSysConfig.getIntValue(MSysConfig.GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS,
GridTable.DEFAULT_GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS, Env.getAD_Client_ID(Env.getCtx()));
m_total = 999999;
Statement stmt = null;
ResultSet rs = null;
try
{
stmt = DB.createStatement();
if (timeout > 0)
stmt.setQueryTimeout(timeout);
rs = stmt.executeQuery(finalSQL);
if (rs.next())
m_total = rs.getInt(1);
}
catch (SQLException e)
{
throw new DBException(e);
if (DB.getDatabase().isQueryTimeout(e))
{
throw new DBException(Msg.getMsg(Env.getCtx(), GridTable.LOAD_TIMEOUT_ERROR_MESSAGE));
}
else
{
throw new DBException(e);
}
}
finally
{