Skip to content

Commit

Permalink
Issue angelozerr#171: Preference for disabling asynchronous requests.
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrtomiak authored and vrubezhny committed Feb 19, 2015
1 parent 18f4983 commit 92c42ef
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 40 deletions.
34 changes: 10 additions & 24 deletions core/tern.core/src/tern/server/AbstractTernServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@
import tern.ITernFileSynchronizer;
import tern.ITernProject;
import tern.TernException;
import tern.server.protocol.ITernResultsAsyncCollector;
import tern.server.protocol.ITernResultsCollector;
import tern.server.protocol.TernDoc;
import tern.server.protocol.TernResultsProcessorsFactory;

/**
* Abstract tern server.
Expand All @@ -38,7 +36,7 @@ public abstract class AbstractTernServer implements ITernServer {
private boolean dispose;
private boolean loadingLocalPlugins;

private ITernServerAsyncRequestProcessor asyncReqProcessor;
private ITernServerRequestProcessor reqProcessor;

private ReentrantReadWriteLock stateLock = new ReentrantReadWriteLock();

Expand Down Expand Up @@ -161,34 +159,22 @@ public boolean isLoadingLocalPlugins() {
@Override
public void request(TernDoc doc, ITernResultsCollector collector)
throws TernException {
ITernServerAsyncRequestProcessor asyncReqProc = this.asyncReqProcessor;
if (!(collector instanceof ITernResultsAsyncCollector)) {
try {
TernResultsProcessorsFactory.makeRequestAndProcess(doc, this,
collector);
} catch (TernException ex) {
throw ex;
} catch (Throwable t) {
throw new TernException(t);
}
} else if (asyncReqProc == null) {
throw new TernException(
"Cannot make an asynchronous request without an asynchronous request processor.");
} else {
asyncReqProc.processRequest(doc,
(ITernResultsAsyncCollector) collector);
if (reqProcessor == null) {
//always provide request processor
reqProcessor = new SynchronousRequestProcessor(this);
}
reqProcessor.processRequest(doc, collector);
}

@Override
public ITernServerAsyncRequestProcessor getAsyncRequestProcessor() {
return asyncReqProcessor;
public ITernServerRequestProcessor getRequestProcessor() {
return reqProcessor;
}

@Override
public void setAsyncRequestProcessor(
ITernServerAsyncRequestProcessor asyncReqProcessor) {
this.asyncReqProcessor = asyncReqProcessor;
public void setRequestProcessor(
ITernServerRequestProcessor reqProcessor) {
this.reqProcessor = reqProcessor;
}

}
5 changes: 2 additions & 3 deletions core/tern.core/src/tern/server/ITernServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,9 @@ void request(TernDoc doc, ITernResultsCollector collector)
*/
boolean isLoadingLocalPlugins();

ITernServerAsyncRequestProcessor getAsyncRequestProcessor();
ITernServerRequestProcessor getRequestProcessor();

void setAsyncRequestProcessor(
ITernServerAsyncRequestProcessor asyncReqProcessor);
void setRequestProcessor(ITernServerRequestProcessor asyncReqProcessor);

IJSONObjectHelper getJSONObjectHelper();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
package tern.server;

import tern.TernException;
import tern.server.protocol.ITernResultsAsyncCollector;
import tern.server.protocol.ITernResultsCollector;
import tern.server.protocol.TernDoc;

public interface ITernServerAsyncRequestProcessor {
public interface ITernServerRequestProcessor {

void processRequest(TernDoc doc, ITernResultsAsyncCollector collector)
void processRequest(TernDoc doc, ITernResultsCollector collector)
throws TernException;

}
48 changes: 48 additions & 0 deletions core/tern.core/src/tern/server/SynchronousRequestProcessor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* Copyright (c) 2015 Genuitec LLC.
* 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
*
* Contributors:
* Piotr Tomiak <piotr@genuitec.com> - initial API and implementation
*/
package tern.server;

import tern.TernException;
import tern.server.protocol.ITernResultsAsyncCollector;
import tern.server.protocol.ITernResultsCollector;
import tern.server.protocol.TernDoc;
import tern.server.protocol.TernResultsProcessorsFactory;

/**
* Basic request processor, which processes requests always in a synchronous
* way.
*/
public class SynchronousRequestProcessor implements ITernServerRequestProcessor {

private ITernServer server;

public SynchronousRequestProcessor(ITernServer server) {
this.server = server;
}

@Override
public void processRequest(TernDoc doc, ITernResultsCollector collector)
throws TernException {
try {
TernResultsProcessorsFactory.makeRequestAndProcess(doc, server,
collector);
// mark collection as done to be super correct
if (collector instanceof ITernResultsAsyncCollector) {
((ITernResultsAsyncCollector) collector).done();
}
} catch (TernException ex) {
throw ex;
} catch (Throwable t) {
throw new TernException(t);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class TernCorePreferenceConstants {
* Server preferences consttants.
*/
public static final String TERN_SERVER_TYPE = "ternServerType"; //$NON-NLS-1$
public static final String DISABLE_ASYNC_REQUESTS = "disableAsyncRequests"; //$NON-NLS-1$

/**
* Tern development preferences constants.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Preferences;

import tern.eclipse.ide.core.ITernRepositoryManager;
import tern.eclipse.ide.core.ITernServerType;
import tern.eclipse.ide.core.TernCorePlugin;
import tern.eclipse.ide.core.preferences.PreferencesSupport;
Expand Down Expand Up @@ -78,6 +77,20 @@ public boolean isLoadingLocalPlugins(IProject project) {
return StringUtils.asBoolean(result, false);
}

/**
* Return false if Tern requests, like autocompletion should not be allowed
* to run asynchronously and timeout.
*
* @param project
* @return true if asynchronous requests should not be allowed.
*/
public boolean isDisableAsynchronousReques(IProject project) {
String result = preferencesSupport.getPreferencesValue(
TernCorePreferenceConstants.DISABLE_ASYNC_REQUESTS, null,
project);
return StringUtils.asBoolean(result, false);
}

/**
* Returns the used tern repository name for the given project.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,12 @@ public void onStop(ITernServer server) {
getFileSynchronizer().cleanIndexedFiles();
}
});
this.ternServer
.setAsyncRequestProcessor(new IDETernServerAsyncReqProcessor(
ternServer));
if (!TernCorePreferencesSupport.getInstance()
.isDisableAsynchronousReques(project)) {
this.ternServer
.setRequestProcessor(new IDETernServerAsyncReqProcessor(
ternServer));
}
copyListeners();
configureConsole();
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@
import tern.TernException;
import tern.eclipse.ide.core.TernCorePlugin;
import tern.server.ITernServer;
import tern.server.ITernServerAsyncRequestProcessor;
import tern.server.ITernServerRequestProcessor;
import tern.server.protocol.ITernResultsAsyncCollector;
import tern.server.protocol.ITernResultsCollector;
import tern.server.protocol.TernResultsProcessorsFactory;
import tern.server.protocol.ITernResultsAsyncCollector.TimeoutReason;
import tern.server.protocol.TernDoc;

public class IDETernServerAsyncReqProcessor extends Job implements
ITernServerAsyncRequestProcessor {
ITernServerRequestProcessor {

private static final long TIMEOUT = 750;

Expand All @@ -40,8 +41,21 @@ public IDETernServerAsyncReqProcessor(ITernServer server) {
}

@Override
public void processRequest(TernDoc doc, ITernResultsAsyncCollector collector)
public void processRequest(TernDoc doc, ITernResultsCollector c)
throws TernException {
if (!(c instanceof ITernResultsAsyncCollector)) {
// need to process request synchronously
try {
TernResultsProcessorsFactory.makeRequestAndProcess(doc, server,
c);
return;
} catch (TernException ex) {
throw ex;
} catch (Throwable t) {
throw new TernException(t);
}
}
ITernResultsAsyncCollector collector = (ITernResultsAsyncCollector) c;
long start = System.currentTimeMillis();
while (this.collector != null
&& (System.currentTimeMillis() - start) < TIMEOUT / 2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public final class TernUIMessages extends NLS {

// Preferences
public static String TernGlobalPreferencesPage_desc;

public static String TernGlobalPreferencesPage_disable_async_reqs;
public static String TernGlobalPreferencesPage_serverType;

// Commons Property preferences
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ PropertyPreferencePage_01=Project Specific Configuration
PropertyPreferencePage_02=Select the project to configure:

TernGlobalPreferencesPage_desc=General Settings for using Tern.
TernGlobalPreferencesPage_disable_async_reqs=Disable asynchronous requests to Tern Server?
TernGlobalPreferencesPage_serverType=Tern server type:

# Properties page
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.ComboFieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IPreferenceStore;
Expand All @@ -36,7 +37,8 @@ public class TernGlobalPreferencesPage extends FieldEditorPreferencePage
public TernGlobalPreferencesPage() {
super(GRID);
setDescription(TernUIMessages.TernGlobalPreferencesPage_desc);
setImageDescriptor(ImageResource.getImageDescriptor(ImageResource.IMG_LOGO));
setImageDescriptor(ImageResource
.getImageDescriptor(ImageResource.IMG_LOGO));
}

@Override
Expand All @@ -46,8 +48,8 @@ protected void createFieldEditors() {
ITernServerType[] serverTypes = TernCorePlugin
.getTernServerTypeManager().getTernServerTypes();
String[][] types = new String[serverTypes.length + 1][2];
types[0][0] = " -- Choose your server type --";
types[0][1] = "";
types[0][0] = " -- Choose your server type --"; //$NON-NLS-1$
types[0][1] = ""; //$NON-NLS-1$

for (int i = 0; i < serverTypes.length; i++) {
types[i + 1][0] = serverTypes[i].getName();
Expand All @@ -59,6 +61,12 @@ protected void createFieldEditors() {
TernUIMessages.TernGlobalPreferencesPage_serverType, types,
getFieldEditorParent());
addField(ternServerEditor);

BooleanFieldEditor asyncRequestsEditor = new BooleanFieldEditor(
TernCorePreferenceConstants.DISABLE_ASYNC_REQUESTS,
TernUIMessages.TernGlobalPreferencesPage_disable_async_reqs,
getFieldEditorParent());
addField(asyncRequestsEditor);
}

@Override
Expand Down

0 comments on commit 92c42ef

Please sign in to comment.