From 38f1a48157fa09daeb1c548be8835f2f2a174f4a Mon Sep 17 00:00:00 2001 From: David McKnight Date: Thu, 28 Feb 2008 16:17:01 +0000 Subject: [PATCH] [220123][dstore] Configurable timeout on irresponsiveness --- .../dstore/core/client/ClientConnection.java | 4 + .../eclipse/dstore/core/model/DataStore.java | 57 ++++++- .../model/IDataStorePreferenceListener.java | 29 ++++ .../core/client/ClientCommandHandler.java | 3 +- .../core/server/ConnectionEstablisher.java | 5 +- .../dstore/internal/core/util/Receiver.java | 40 ++++- .../dstore/internal/core/util/XMLparser.java | 65 ++++---- .../dstore/DStoreConnectorService.java | 25 ++- .../dstore/IUniversalDStoreConstants.java | 9 ++ .../dstore/DStoreResources.java | 9 ++ .../dstore/DStoreResources.properties | 10 +- .../propertypages/DStorePreferencePage.java | 143 ++++++++++++++++-- 12 files changed, 348 insertions(+), 51 deletions(-) create mode 100644 rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IDataStorePreferenceListener.java diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientConnection.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientConnection.java index ffeefd0c35e..3ce6d58c629 100644 --- a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientConnection.java +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/client/ClientConnection.java @@ -15,6 +15,7 @@ * David McKnight (IBM) - [205986] daemon handshake needs a timeout * David McKnight (IBM) - [218685] [dstore] Unable to connect when using SSL. * Martin Oberhuber (Wind River) - [219260][dstore][regression] Cannot connect to dstore daemon + * David McKnight (IBM) [220123][dstore] Configurable timeout on irresponsiveness *******************************************************************************/ package org.eclipse.dstore.core.client; @@ -319,6 +320,7 @@ public class ClientConnection { if (_isConnected) { + _dataStore.removeDataStorePreferenceListener(_receiver); _dataStore.setConnected(false); if (_isRemote) @@ -332,6 +334,7 @@ public class ClientConnection _commandHandler.finish(); + try { Thread.sleep(200); @@ -602,6 +605,7 @@ public class ClientConnection _updateHandler.setDataStore(_dataStore); _receiver = new ClientReceiver(_theSocket, _dataStore); + _dataStore.addDataStorePreferenceListener(_receiver); _receiver.start(); _isConnected = true; diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStore.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStore.java index 74dd5813a61..6ed18d2be89 100644 --- a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStore.java +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/DataStore.java @@ -15,6 +15,7 @@ * Michael Berger (IBM) - 146326 fixed erroneously disconnected dstore elements. * Michael Berger (IBM) - 145799 added refresh() method with depth parameter. * David McKnight (IBM) - 202822 findDeleted should not be synchronized + * David McKnight (IBM) [220123][dstore] Configurable timeout on irresponsiveness *******************************************************************************/ package org.eclipse.dstore.core.model; @@ -104,6 +105,9 @@ public final class DataStore private ArrayList _localClassLoaders; private HashMap _dataStorePreferences; + private List _dataStorePreferenceListeners; + + private ISSLProperties _sslProperties; private boolean _autoRefresh; @@ -2066,11 +2070,28 @@ public final class DataStore DataElement cmd = findCommandDescriptor(DataStoreSchema.C_SCHEMA);//localDescriptorQuery(_root.getDescriptor(), DataStoreSchema.C_SCHEMA, 1); return command(cmd, _dummy); } - + + /** + * Sets a property value preference on the client and server datastore + * @param property the property to set + * @param value the value of the property + */ public void setPreference(String property, String value) + { + setPreference(property, value, true); + } + + /** + * Sets a property value preference on the client datastore. If remoteAndLocal is set + * then the property get set on the server side as well as the client. + * @param property the property to set + * @param value the value of the property + * @param remoteAndLocal whether to propagate the change to the server + */ + public void setPreference(String property, String value, boolean remoteAndLocal) { _dataStorePreferences.put(property, value); - if (isVirtual()) + if (isVirtual() && remoteAndLocal) { DataElement cmd = findCommandDescriptor(DataStoreSchema.C_SET_PREFERENCE); if (cmd != null) @@ -2079,6 +2100,12 @@ public final class DataStore prefObj.setAttribute(DE.A_VALUE, value); command(cmd, prefObj, true); } + } + + // notify that preferences have changed + for (int i = 0; i < _dataStorePreferenceListeners.size(); i++){ + IDataStorePreferenceListener listener = (IDataStorePreferenceListener)_dataStorePreferenceListeners.get(i); + listener.preferenceChanged(property, value); } } @@ -2087,6 +2114,29 @@ public final class DataStore return (String)_dataStorePreferences.get(property); } + /** + * Adds a preference change listener to the DataStore + * @param listener + */ + public void addDataStorePreferenceListener(IDataStorePreferenceListener listener){ + _dataStorePreferenceListeners.add(listener); + } + + /** + * Removes a specific preference change listener from the Datastore + * @param listener + */ + public void removeDataStorePreferenceListener(IDataStorePreferenceListener listener){ + _dataStorePreferenceListeners.remove(listener); + } + + /** + * Removes all the preference change listeners + */ + public void removeAllDataStorePreferenceListeners(){ + _dataStorePreferenceListeners.clear(); + } + /** * Used to load and initialize a new miner on the host * @param minerId the qualified classname of the miner to load @@ -3469,12 +3519,14 @@ public final class DataStore _lastCreatedElements = new ArrayList(); _minersLocations = new ArrayList(); + _random = new Random(System.currentTimeMillis()); _objDescriptorMap = new HashMap(100); _cmdDescriptorMap = new HashMap(100); _relDescriptorMap = new HashMap(100); _dataStorePreferences = new HashMap(10); + _dataStorePreferenceListeners = new ArrayList(); _hashMap = new HashMap(2 * _initialSize); _recycled = new ArrayList(_initialSize); @@ -3497,6 +3549,7 @@ public final class DataStore { _serverIdleShutdownTimeout = Integer.parseInt(serverIdleShutdownTimeout); } + } diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IDataStorePreferenceListener.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IDataStorePreferenceListener.java new file mode 100644 index 00000000000..f751b613d4e --- /dev/null +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/core/model/IDataStorePreferenceListener.java @@ -0,0 +1,29 @@ +/******************************************************************************** + * Copyright (c) 2008 IBM Corporation. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Initial Contributors: + * The following IBM employees contributed to the Remote System Explorer + * component that contains this file: David McKnight. + * + * Contributors: + * David McKnight (IBM) [220123][dstore] Configurable timeout on irresponsiveness + ********************************************************************************/ +package org.eclipse.dstore.core.model; + +/** + * Classes that implement this and add themselves to the DataStore preference listeners + * get called each time a preference is changed. + */ +public interface IDataStorePreferenceListener { + + /** + * A DataStore preference has changed + * @param property the property that has changed + * @param value the value of the property + */ + public void preferenceChanged(String property, String value); + +} diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/client/ClientCommandHandler.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/client/ClientCommandHandler.java index 07c301a7436..aeb6540446f 100644 --- a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/client/ClientCommandHandler.java +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/client/ClientCommandHandler.java @@ -12,7 +12,7 @@ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley. * * Contributors: - * {Name} (company) - description of contribution. + * David McKnight (IBM) [220123][dstore] Configurable timeout on irresponsiveness *******************************************************************************/ package org.eclipse.dstore.internal.core.client; @@ -379,4 +379,5 @@ public class ClientCommandHandler extends CommandHandler super.waitForInput(); } } + } diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/server/ConnectionEstablisher.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/server/ConnectionEstablisher.java index 82bf50c285f..c6126e973d8 100644 --- a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/server/ConnectionEstablisher.java +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/server/ConnectionEstablisher.java @@ -12,7 +12,7 @@ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley. * * Contributors: - * {Name} (company) - description of contribution. + * David McKnight (IBM) [220123][dstore] Configurable timeout on irresponsiveness *******************************************************************************/ package org.eclipse.dstore.internal.core.server; @@ -146,6 +146,7 @@ public class ConnectionEstablisher { _updateHandler.removeSenderWith(receiver.socket()); _receivers.remove(receiver); + _dataStore.removeDataStorePreferenceListener(receiver); //if (_receivers.size() == 0) { _continue = false; @@ -185,6 +186,8 @@ public class ConnectionEstablisher newSocket.setKeepAlive(true); ServerReceiver receiver = new ServerReceiver(newSocket, this); + _dataStore.addDataStorePreferenceListener(receiver); + Sender sender = new Sender(newSocket, _dataStore); // add this connection to list of elements diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/util/Receiver.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/util/Receiver.java index 66801f9537f..85e4bacfb58 100644 --- a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/util/Receiver.java +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/util/Receiver.java @@ -12,7 +12,7 @@ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley. * * Contributors: - * {Name} (company) - description of contribution. + * David McKnight (IBM) [220123][dstore] Configurable timeout on irresponsiveness *******************************************************************************/ package org.eclipse.dstore.internal.core.util; @@ -24,12 +24,13 @@ import java.net.UnknownHostException; import org.eclipse.dstore.core.model.DataElement; import org.eclipse.dstore.core.model.DataStore; +import org.eclipse.dstore.core.model.IDataStorePreferenceListener; /** * This class is used for receiving data from a socket in the DataStore * communication layer. */ -public abstract class Receiver extends Thread +public abstract class Receiver extends Thread implements IDataStorePreferenceListener { @@ -67,6 +68,20 @@ public abstract class Receiver extends Thread { //System.out.println("Receiver:" + ioe); } + + // keepalive preferences + String keepAliveResponseTimeout = System.getProperty(XMLparser.KEEPALIVE_RESPONSE_TIMEOUT_PREFERENCE); + if (keepAliveResponseTimeout != null){ + preferenceChanged(XMLparser.KEEPALIVE_RESPONSE_TIMEOUT_PREFERENCE, keepAliveResponseTimeout); + } + String iosocketReadTimeout = System.getProperty(XMLparser.IO_SOCKET_READ_TIMEOUT_PREFERENCE); + if (iosocketReadTimeout != null){ + preferenceChanged(XMLparser.IO_SOCKET_READ_TIMEOUT_PREFERENCE, iosocketReadTimeout); + } + String enableKeepAlive = System.getProperty(XMLparser.KEEPALIVE_ENABLED_PREFERENCE); + if (enableKeepAlive != null){ + preferenceChanged(XMLparser.KEEPALIVE_ENABLED_PREFERENCE, enableKeepAlive); + } } /** @@ -164,4 +179,25 @@ public abstract class Receiver extends Thread * @param e an exception that occurred */ public abstract void handleError(Throwable e); + + + public void preferenceChanged(String property, String value) + { + //System.out.println("setting preference: "+property + "="+value); + if (property.equals(XMLparser.IO_SOCKET_READ_TIMEOUT_PREFERENCE)){ + int timeout = Integer.parseInt(value); + _xmlParser.setIOSocketReadTimeout(timeout); + } + else if (property.equals(XMLparser.KEEPALIVE_RESPONSE_TIMEOUT_PREFERENCE)){ + int timeout = Integer.parseInt(value); + _xmlParser.setKeepaliveResponseTimeout(timeout); + } + else if (property.equals(XMLparser.KEEPALIVE_ENABLED_PREFERENCE)){ + boolean enable = true; + if (value.equals("false")) //$NON-NLS-1$ + enable = false; + _xmlParser.setEnableKeepalive(enable); + } + } + } diff --git a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/util/XMLparser.java b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/util/XMLparser.java index 985100c15af..18c3c11578d 100644 --- a/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/util/XMLparser.java +++ b/rse/plugins/org.eclipse.dstore.core/src/org/eclipse/dstore/internal/core/util/XMLparser.java @@ -12,7 +12,7 @@ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley. * * Contributors: - * {Name} (company) - description of contribution. + * David McKnight (IBM) [220123][dstore] Configurable timeout on irresponsiveness *******************************************************************************/ package org.eclipse.dstore.internal.core.util; @@ -50,9 +50,13 @@ import org.eclipse.dstore.core.model.DataStoreResources; */ public class XMLparser { + public static final String KEEPALIVE_RESPONSE_TIMEOUT_PREFERENCE = "DSTORE_KEEPALIVE_RESPONSE_TIMEOUT"; //$NON-NLS-1$ + public static final String IO_SOCKET_READ_TIMEOUT_PREFERENCE = "DSTORE_IO_SOCKET_READ_TIMEOUT"; //$NON-NLS-1$ + public static final String KEEPALIVE_ENABLED_PREFERENCE = "DSTORE_KEEPALIVE_ENABLED"; //$NON-NLS-1$ + + public int IO_SOCKET_READ_TIMEOUT = 3600000; + public long KEEPALIVE_RESPONSE_TIMEOUT = 60000; - public static final int IO_SOCKET_READ_TIMEOUT = 3600000; - public static final long KEEPALIVE_RESPONSE_TIMEOUT = 60000; public static final boolean VERBOSE_KEEPALIVE = false; private DataStore _dataStore; @@ -116,8 +120,37 @@ public class XMLparser _objStack = new Stack(); _maxBuffer = 100000; _byteBuffer = new byte[_maxBuffer]; + } + /** + * Set whether to enable keepalive + * @param enable + */ + public void setEnableKeepalive(boolean enable){ + // if false, we ignore the keepalive stuff + _isKeepAliveCompatible = enable; + } + + /** + * Set the keepalive response timeout + * @param timeout the time to wait for a response after + * initiating a keepalivfe request + */ + public void setKeepaliveResponseTimeout(int timeout){ + // the new value will be picked up on the next readLine() call + KEEPALIVE_RESPONSE_TIMEOUT = timeout; + } + + /** + * Set the socket read timeout + * @param timeout the time to wait before initiating a keepalive request + */ + public void setIOSocketReadTimeout(int timeout){ + // the new value will be picked up on the next readLine() call + IO_SOCKET_READ_TIMEOUT = timeout; + } + /** * Read a file from the pipe * @param reader the pipe reader @@ -149,32 +182,6 @@ public class XMLparser } int written = 0; - -// // hack to deal with platform inconsistencies -// // only needed on the server side -// if (!_dataStore.isVirtual()) -// { -// try -// { -// synchronized (reader) -// { -// int first = reader.read(); -// -// if (first != 10) { -// written = 1; -// buffer[0] = (byte) first; -// } -// else { -// System.out.println("First byte is 10!"); -// } -// } -// } -// catch (IOException e) -// { -// _dataStore.trace(e); -// } -// } - while (written < size) { try diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/DStoreConnectorService.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/DStoreConnectorService.java index bb995dd3285..205ffca48cd 100644 --- a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/DStoreConnectorService.java +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/DStoreConnectorService.java @@ -24,6 +24,7 @@ * David McKnight (IBM) - [216596] dstore preferences (timeout, and others) * David McKnight (IBM) - [216252] [api][nls] Resource Strings specific to subsystems should be moved from rse.ui into files.ui / shells.ui / processes.ui where possible * David McKnight (IBM) - [218685] [api][breaking][dstore] Unable to connect when using SSL. + * David McKnight (IBM) - [220123][dstore] Configurable timeout on irresponsiveness *******************************************************************************/ package org.eclipse.rse.connectorservice.dstore; @@ -52,6 +53,7 @@ import org.eclipse.dstore.core.model.IDataStoreConstants; import org.eclipse.dstore.core.model.IDataStoreProvider; import org.eclipse.dstore.core.model.ISSLProperties; import org.eclipse.dstore.internal.core.client.ClientSSLProperties; +import org.eclipse.dstore.internal.core.util.XMLparser; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.osgi.util.NLS; @@ -952,9 +954,28 @@ public class DStoreConnectorService extends StandardConnectorService implements { // register the preference for remote class caching with the datastore boolean cacheRemoteClasses = store.getBoolean(IUniversalDStoreConstants.RESID_PREF_CACHE_REMOTE_CLASSES); + + // this preference is set on the server side + dataStore.setPreference(RemoteClassLoader.CACHING_PREFERENCE, cacheRemoteClasses ? "true" : "false", true); //$NON-NLS-1$ //$NON-NLS-2$ - dataStore.setPreference(RemoteClassLoader.CACHING_PREFERENCE, cacheRemoteClasses ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$ - + if (serverVersion >= 9){ // keepalive preferences + boolean doKeepalive = store.getBoolean(IUniversalDStoreConstants.RESID_PREF_DO_KEEPALIVE); + + int keepaliveResponseTimeout = store.getInt(IUniversalDStoreConstants.RESID_PREF_KEEPALIVE_RESPONSE_TIMEOUT); + if (keepaliveResponseTimeout == 0){ // use the default + keepaliveResponseTimeout = IUniversalDStoreConstants.DEFAULT_PREF_KEEPALIVE_RESPONSE_TIMEOUT; + } + + int socketTimeout = store.getInt(IUniversalDStoreConstants.RESID_PREF_SOCKET_READ_TIMEOUT); + if (socketTimeout == 0){ // use the default + socketTimeout = IUniversalDStoreConstants.DEFAULT_PREF_SOCKET_READ_TIMEOUT; + } + + // these preferences are only for the client + dataStore.setPreference(XMLparser.KEEPALIVE_ENABLED_PREFERENCE, doKeepalive ? "true" : "false", false); //$NON-NLS-1$//$NON-NLS-2$ + dataStore.setPreference(XMLparser.KEEPALIVE_RESPONSE_TIMEOUT_PREFERENCE, ""+ keepaliveResponseTimeout, false); //$NON-NLS-1$ + dataStore.setPreference(XMLparser.IO_SOCKET_READ_TIMEOUT_PREFERENCE, ""+socketTimeout, false); //$NON-NLS-1$ + } } else { diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalDStoreConstants.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalDStoreConstants.java index 2d1ec319565..578b177f9a1 100644 --- a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalDStoreConstants.java +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/connectorservice/dstore/IUniversalDStoreConstants.java @@ -15,6 +15,7 @@ * {Name} (company) - description of contribution. * David McKnight (IBM) - [216596] dstore preferences (timeout, and others) * David McKnight (IBM) - [218685] [api][breaking][dstore] Unable to connect when using SSL. + * David McKnight (IBM) - [220123][dstore] Configurable timeout on irresponsiveness *******************************************************************************/ package org.eclipse.rse.connectorservice.dstore; @@ -67,6 +68,14 @@ public interface IUniversalDStoreConstants public static final String RESID_PREF_DO_KEEPALIVE = RESID_PREF_PREFIX + "dokeepalive"; //$NON-NLS-1$ public static final boolean DEFAULT_PREF_DO_KEEPALIVE = true; + public static final String RESID_PREF_KEEPALIVE_RESPONSE_TIMEOUT = RESID_PREF_PREFIX + "keepalivetimeout"; + public static final int DEFAULT_PREF_KEEPALIVE_RESPONSE_TIMEOUT = 60000; + + public static final String RESID_PREF_SOCKET_READ_TIMEOUT = RESID_PREF_PREFIX + "socketreadtimeout"; + public static final int DEFAULT_PREF_SOCKET_READ_TIMEOUT = 3600000; + + + public static final String ALERT_MISMATCHED_SERVER = RESID_PREFIX + "alert.mismatched.server"; //$NON-NLS-1$ public static final boolean DEFAULT_ALERT_MISMATCHED_SERVER = true; } diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/internal/connectorservice/dstore/DStoreResources.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/internal/connectorservice/dstore/DStoreResources.java index 52c26a064e5..f05319ec972 100644 --- a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/internal/connectorservice/dstore/DStoreResources.java +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/internal/connectorservice/dstore/DStoreResources.java @@ -10,6 +10,7 @@ * * Contributors: * David McKnight (IBM) - [216596] dstore preferences (timeout, and others) + * David McKnight (IBM) - [220123][dstore] Configurable timeout on irresponsiveness ********************************************************************************/ package org.eclipse.rse.internal.connectorservice.dstore; @@ -25,11 +26,19 @@ public class DStoreResources extends NLS { public static String RESID_PREFERENCE_DO_KEEPALIVE_LABEL; public static String RESID_PREFERENCE_DO_KEEPALIVE_TOOLTIP; + public static String RESID_PREFERENCE_KEEPALIVE_SOCKET_READ_TIMEOUT_LABEL; + public static String RESID_PREFERENCE_KEEPALIVE_SOCKET_READ_TIMEOUT_TOOLTIP; + + public static String RESID_PREFERENCE_KEEPALIVE_RESPONSE_TIMEOUT_LABEL; + public static String RESID_PREFERENCE_KEEPALIVE_RESPONSE_TIMEOUT_TOOLTIP; + public static String RESID_PREFERENCE_CACHE_REMOTE_CLASSES_LABEL; public static String RESID_PREFERENCE_CACHE_REMOTE_CLASSES_TOOLTIP; public static String RESID_PREFERENCE_SHOW_MISMATCHED_SERVER_LABEL; public static String RESID_PREFERENCE_SHOW_MISMATCHED_SERVER_TOOLTIP; + + public static String RESID_PREFERENCE_KEEPALIVE_LABEL; static { diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/internal/connectorservice/dstore/DStoreResources.properties b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/internal/connectorservice/dstore/DStoreResources.properties index 396e35c4b49..05267726a88 100644 --- a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/internal/connectorservice/dstore/DStoreResources.properties +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/internal/connectorservice/dstore/DStoreResources.properties @@ -10,6 +10,7 @@ # Contributors: # David McKnight (IBM) - [216596] dstore preferences (timeout, and others) +# David McKnight (IBM) - [220123][dstore] Configurable timeout on irresponsiveness ################################################################################# # NLS_MESSAGEFORMAT_VAR @@ -21,9 +22,16 @@ RESID_PREFERENCE_CONNECTION_TIMEOUT_TOOLTIP=Time to wait for establishing a Data RESID_PREFERENCE_DO_KEEPALIVE_LABEL=Enable Keepalive RESID_PREFERENCE_DO_KEEPALIVE_TOOLTIP=Keep DataStore connections alive when idle. +RESID_PREFERENCE_KEEPALIVE_SOCKET_READ_TIMEOUT_LABEL=Socket Read Timeout (ms) +RESID_PREFERENCE_KEEPALIVE_SOCKET_READ_TIMEOUT_TOOLTIP=Time to wait for input on a socket before initiating a keepalive request + +RESID_PREFERENCE_KEEPALIVE_RESPONSE_TIMEOUT_LABEL=Keepalive Response Timeout (ms) +RESID_PREFERENCE_KEEPALIVE_RESPONSE_TIMEOUT_TOOLTIP=Time to wait for a response to a keepalive request + RESID_PREFERENCE_CACHE_REMOTE_CLASSES_LABEL=Cache Remote Classes RESID_PREFERENCE_CACHE_REMOTE_CLASSES_TOOLTIP=Cache remote server classes. This is only useful when all required classes are unavailable on the server side. RESID_PREFERENCE_SHOW_MISMATCHED_SERVER_LABEL=Show Mismatched Server Warning RESID_PREFERENCE_SHOW_MISMATCHED_SERVER_TOOLTIP=Show a warning when the DataStore server is compatible but older or newer then the current client. - \ No newline at end of file + +RESID_PREFERENCE_KEEPALIVE_LABEL=Keepalive \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/internal/connectorservice/dstore/ui/propertypages/DStorePreferencePage.java b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/internal/connectorservice/dstore/ui/propertypages/DStorePreferencePage.java index 031cce3bd5d..65c4846e4c0 100644 --- a/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/internal/connectorservice/dstore/ui/propertypages/DStorePreferencePage.java +++ b/rse/plugins/org.eclipse.rse.connectorservice.dstore/src/org/eclipse/rse/internal/connectorservice/dstore/ui/propertypages/DStorePreferencePage.java @@ -10,6 +10,7 @@ * * Contributors: * David McKnight (IBM) - [216596] dstore preferences (timeout, and others) + * David McKnight (IBM) - [220123][dstore] Configurable timeout on irresponsiveness ********************************************************************************/ package org.eclipse.rse.internal.connectorservice.dstore.ui.propertypages; @@ -28,6 +29,7 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbench; @@ -38,24 +40,31 @@ public class DStorePreferencePage extends PreferencePage implements IWorkbenchPr private Text _connectionTimeout; private Button _doKeepaliveButton; + private Text _keepaliveResponseTimeout; + private Text _socketReadTimeout; + private Button _cacheRemoteClassesButton; private Button _showMismatchedServerWarningButton; protected Control createContents(Composite gparent) { Composite parent = SystemWidgetHelpers.createComposite(gparent, 2); - + GridLayout layout = new GridLayout(); layout.numColumns = 2; parent.setLayout(layout); parent.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING)); + + Composite connectComposite = SystemWidgetHelpers.createComposite(parent, 2); - SystemWidgetHelpers.createLabel(parent, DStoreResources.RESID_PREFERENCE_CONNECTION_TIMEOUT_LABEL); + SystemWidgetHelpers.createLabel(connectComposite, DStoreResources.RESID_PREFERENCE_CONNECTION_TIMEOUT_LABEL); - _connectionTimeout = new Text(parent, SWT.BORDER); - GridData gd = new GridData(SWT.BEGINNING, SWT.CENTER, false, false); + _connectionTimeout = new Text(connectComposite, SWT.BORDER); + //GridData gd = new GridData(SWT.BEGINNING, SWT.CENTER, false, false); + GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); gd.widthHint = 75; - _connectionTimeout.setLayoutData(gd); - _connectionTimeout.setTextLimit(5); + gd.horizontalSpan =1; + _connectionTimeout.setLayoutData(gd); + _connectionTimeout.setTextLimit(10); _connectionTimeout.setToolTipText(DStoreResources.RESID_PREFERENCE_CONNECTION_TIMEOUT_TOOLTIP); _connectionTimeout.addVerifyListener(new VerifyListener() { @@ -69,11 +78,7 @@ public class DStorePreferencePage extends PreferencePage implements IWorkbenchPr } } }); - - _doKeepaliveButton = SystemWidgetHelpers.createCheckBox(parent, DStoreResources.RESID_PREFERENCE_DO_KEEPALIVE_LABEL, this); - _doKeepaliveButton.setToolTipText(DStoreResources.RESID_PREFERENCE_DO_KEEPALIVE_TOOLTIP); - _doKeepaliveButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, true, false)); - ((GridData)_doKeepaliveButton.getLayoutData()).horizontalSpan = 2; + _cacheRemoteClassesButton = SystemWidgetHelpers.createCheckBox(parent, DStoreResources.RESID_PREFERENCE_CACHE_REMOTE_CLASSES_LABEL, this); _cacheRemoteClassesButton.setToolTipText(DStoreResources.RESID_PREFERENCE_CACHE_REMOTE_CLASSES_TOOLTIP); @@ -86,6 +91,70 @@ public class DStorePreferencePage extends PreferencePage implements IWorkbenchPr ((GridData)_showMismatchedServerWarningButton.getLayoutData()).horizontalSpan = 2; + // keepalive stuff + Group keepaliveGroup = SystemWidgetHelpers.createGroupComposite(parent, 2, DStoreResources.RESID_PREFERENCE_KEEPALIVE_LABEL); + layout = new GridLayout(); + layout.numColumns = 2; + keepaliveGroup.setLayout(layout); + GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL + | GridData.GRAB_HORIZONTAL); + keepaliveGroup.setLayoutData(data); + + + + _doKeepaliveButton = SystemWidgetHelpers.createCheckBox(keepaliveGroup, DStoreResources.RESID_PREFERENCE_DO_KEEPALIVE_LABEL, this); + _doKeepaliveButton.setToolTipText(DStoreResources.RESID_PREFERENCE_DO_KEEPALIVE_TOOLTIP); + _doKeepaliveButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, true, false)); + ((GridData)_doKeepaliveButton.getLayoutData()).horizontalSpan = 2; + + + SystemWidgetHelpers.createLabel(keepaliveGroup, DStoreResources.RESID_PREFERENCE_KEEPALIVE_SOCKET_READ_TIMEOUT_LABEL); + + _socketReadTimeout = new Text(keepaliveGroup, SWT.BORDER); + gd = new GridData(SWT.BEGINNING, SWT.CENTER, false, false); + gd.widthHint = 75; + gd.horizontalSpan =1; + _socketReadTimeout.setLayoutData(gd); + _socketReadTimeout.setTextLimit(10); + _socketReadTimeout.setToolTipText(DStoreResources.RESID_PREFERENCE_KEEPALIVE_SOCKET_READ_TIMEOUT_TOOLTIP); + _socketReadTimeout.addVerifyListener(new VerifyListener() + { + public void verifyText(VerifyEvent e) + { + e.doit = true; + for (int loop = 0; loop < e.text.length(); loop++) + { + if (!Character.isDigit(e.text.charAt(loop))) + e.doit = false; + } + } + }); + + SystemWidgetHelpers.createLabel(keepaliveGroup, DStoreResources.RESID_PREFERENCE_KEEPALIVE_RESPONSE_TIMEOUT_LABEL); + + _keepaliveResponseTimeout = new Text(keepaliveGroup, SWT.BORDER); + gd = new GridData(SWT.BEGINNING, SWT.CENTER, false, false); + gd.widthHint = 75; + gd.horizontalSpan =1; + _keepaliveResponseTimeout.setLayoutData(gd); + _keepaliveResponseTimeout.setTextLimit(10); + _keepaliveResponseTimeout.setToolTipText(DStoreResources.RESID_PREFERENCE_KEEPALIVE_RESPONSE_TIMEOUT_TOOLTIP); + _keepaliveResponseTimeout.addVerifyListener(new VerifyListener() + { + public void verifyText(VerifyEvent e) + { + e.doit = true; + for (int loop = 0; loop < e.text.length(); loop++) + { + if (!Character.isDigit(e.text.charAt(loop))) + e.doit = false; + } + } + }); + + + + initControls(); return parent; } @@ -131,6 +200,28 @@ public class DStorePreferencePage extends PreferencePage implements IWorkbenchPr } _doKeepaliveButton.setSelection(doKeepalive); + int socketTimeout = 0; + if (store.contains(IUniversalDStoreConstants.RESID_PREF_SOCKET_READ_TIMEOUT)){ + socketTimeout = store.getInt(IUniversalDStoreConstants.RESID_PREF_SOCKET_READ_TIMEOUT); + } + else { + socketTimeout = IUniversalDStoreConstants.DEFAULT_PREF_SOCKET_READ_TIMEOUT; + store.setDefault(IUniversalDStoreConstants.RESID_PREF_SOCKET_READ_TIMEOUT, socketTimeout); + } + _socketReadTimeout.setText(""+socketTimeout); //$NON-NLS-1$ + _socketReadTimeout.setEnabled(doKeepalive); + + int keepaliveTimeout = 0; + if (store.contains(IUniversalDStoreConstants.RESID_PREF_KEEPALIVE_RESPONSE_TIMEOUT)){ + keepaliveTimeout = store.getInt(IUniversalDStoreConstants.RESID_PREF_KEEPALIVE_RESPONSE_TIMEOUT); + } + else { + keepaliveTimeout = IUniversalDStoreConstants.DEFAULT_PREF_KEEPALIVE_RESPONSE_TIMEOUT; + store.setDefault(IUniversalDStoreConstants.RESID_PREF_KEEPALIVE_RESPONSE_TIMEOUT, keepaliveTimeout); + } + _keepaliveResponseTimeout.setText(""+keepaliveTimeout); //$NON-NLS-1$ + _keepaliveResponseTimeout.setEnabled(doKeepalive); + // show mismatched server warning boolean showMismatchedWarning = false; if (store.contains(IUniversalDStoreConstants.ALERT_MISMATCHED_SERVER)){ @@ -157,6 +248,16 @@ public class DStorePreferencePage extends PreferencePage implements IWorkbenchPr boolean doKeepalive = _doKeepaliveButton.getSelection(); store.setValue(IUniversalDStoreConstants.RESID_PREF_DO_KEEPALIVE, doKeepalive); + // socket read timeout + String socketTimeoutStr = _socketReadTimeout.getText(); + int socketTimeout = Integer.parseInt(socketTimeoutStr); + store.setValue(IUniversalDStoreConstants.RESID_PREF_SOCKET_READ_TIMEOUT, socketTimeout); + + // keepalive response timeout + String keepaliveTimeoutStr = _keepaliveResponseTimeout.getText(); + int keepaliveTimeout = Integer.parseInt(keepaliveTimeoutStr); + store.setValue(IUniversalDStoreConstants.RESID_PREF_KEEPALIVE_RESPONSE_TIMEOUT, keepaliveTimeout); + // cache remote classes boolean cacheRemoteClasses = _cacheRemoteClassesButton.getSelection(); store.setValue(IUniversalDStoreConstants.RESID_PREF_CACHE_REMOTE_CLASSES, cacheRemoteClasses); @@ -176,6 +277,17 @@ public class DStorePreferencePage extends PreferencePage implements IWorkbenchPr boolean doKeepalive = IUniversalDStoreConstants.DEFAULT_PREF_DO_KEEPALIVE; _doKeepaliveButton.setSelection(doKeepalive); + // socket read timeout + int socketTimeout = IUniversalDStoreConstants.DEFAULT_PREF_SOCKET_READ_TIMEOUT; + _socketReadTimeout.setText(""+socketTimeout); //$NON-NLS-1$ + _socketReadTimeout.setEnabled(doKeepalive); + + // keepalive response timeout + int keepaliveTimeout = IUniversalDStoreConstants.DEFAULT_PREF_KEEPALIVE_RESPONSE_TIMEOUT; + _keepaliveResponseTimeout.setText(""+keepaliveTimeout); //$NON-NLS-1$ + _keepaliveResponseTimeout.setEnabled(doKeepalive); + + // show mismatched server warning boolean showMismatchedWarning = IUniversalDStoreConstants.DEFAULT_ALERT_MISMATCHED_SERVER; _showMismatchedServerWarningButton.setSelection(showMismatchedWarning); @@ -191,8 +303,13 @@ public class DStorePreferencePage extends PreferencePage implements IWorkbenchPr } public void handleEvent(Event event) { - // TODO Auto-generated method stub - + if (event.widget == _doKeepaliveButton){ + boolean isEnabled = _doKeepaliveButton.getSelection(); + + _socketReadTimeout.setEnabled(isEnabled); + _keepaliveResponseTimeout.setEnabled(isEnabled); + + } } public boolean performOk() {