Fix issue with CachinhModelProvider not caching 'failed' results
Also tweak some timeout values to try to make dynamic CA and reconcile more responsive.
This commit is contained in:
@@ -27,7 +27,7 @@ sp_cleanup.make_variable_declarations_final=false
|
||||
sp_cleanup.never_use_blocks=false
|
||||
sp_cleanup.never_use_parentheses_in_expressions=true
|
||||
sp_cleanup.on_save_use_additional_actions=true
|
||||
sp_cleanup.organize_imports=true
|
||||
sp_cleanup.organize_imports=false
|
||||
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
|
||||
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
|
||||
sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
|
||||
|
||||
@@ -37,7 +37,7 @@ public abstract class BoshCommandBasedModelProvider<T> implements DynamicModelPr
|
||||
|
||||
private final YamlParser yamlParser;
|
||||
protected final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
protected Duration CMD_TIMEOUT = Duration.ofSeconds(10);
|
||||
protected Duration CMD_TIMEOUT = Duration.ofSeconds(3);
|
||||
|
||||
protected BoshCommandBasedModelProvider() {
|
||||
Representer representer = new Representer();
|
||||
@@ -76,10 +76,15 @@ public abstract class BoshCommandBasedModelProvider<T> implements DynamicModelPr
|
||||
|
||||
protected String executeCommand(ExternalCommand command) throws Exception {
|
||||
Log.info("executing cmd: "+command);
|
||||
ExternalProcess process = new ExternalProcess(getWorkingDir(), command, true, CMD_TIMEOUT);
|
||||
Log.info("executing cmd DONE: "+process);
|
||||
String out = process.getOut();
|
||||
return out;
|
||||
try {
|
||||
ExternalProcess process = new ExternalProcess(getWorkingDir(), command, true, CMD_TIMEOUT);
|
||||
Log.info("executing cmd SUCCESS: "+process);
|
||||
String out = process.getOut();
|
||||
return out;
|
||||
} catch (Exception e) {
|
||||
Log.log("executing cmd FAILED", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
protected File getWorkingDir() {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.bosh.models;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -29,9 +30,9 @@ public class CachingModelProvider<T> implements DynamicModelProvider<T> {
|
||||
*/
|
||||
private static final Object NULL_KEY = new Object();
|
||||
|
||||
private long timeout = 15;
|
||||
private long timeout = 30;
|
||||
private TimeUnit timeoutUnit = TimeUnit.SECONDS;
|
||||
private Cache<Object, T> cache = createCache();
|
||||
private Cache<Object, CompletableFuture<T>> cache = createCache();
|
||||
|
||||
private final DynamicModelProvider<T> delegate;
|
||||
|
||||
@@ -48,7 +49,7 @@ public class CachingModelProvider<T> implements DynamicModelProvider<T> {
|
||||
*/
|
||||
private Function<DynamicSchemaContext, Object> keyGetter = (dc) -> "WHATEVER";
|
||||
|
||||
protected Cache<Object, T> createCache() {
|
||||
protected Cache<Object, CompletableFuture<T>> createCache() {
|
||||
return CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(timeout, timeoutUnit)
|
||||
.build();
|
||||
@@ -67,7 +68,19 @@ public class CachingModelProvider<T> implements DynamicModelProvider<T> {
|
||||
//guava cache doesn't like null key
|
||||
key = NULL_KEY;
|
||||
}
|
||||
return cache.get(key, () -> delegate.getModel(dc));
|
||||
CompletableFuture<T> cached;
|
||||
synchronized (this) {
|
||||
cached = cache.get(key, () -> {
|
||||
try {
|
||||
return CompletableFuture.completedFuture(delegate.getModel(dc));
|
||||
} catch (Throwable e) {
|
||||
CompletableFuture<T> failed = new CompletableFuture<>();
|
||||
failed.completeExceptionally(e);
|
||||
return failed;
|
||||
}
|
||||
});
|
||||
}
|
||||
return cached.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ package org.springframework.ide.vscode.bosh.mocks;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.springframework.ide.vscode.bosh.BoshCommandCloudConfigProviderTest;
|
||||
import org.springframework.ide.vscode.bosh.models.BoshCommandCloudConfigProvider;
|
||||
import org.springframework.ide.vscode.bosh.models.BoshCommandCloudConfigProviderTest;
|
||||
import org.springframework.ide.vscode.commons.util.ExternalCommand;
|
||||
import org.springframework.ide.vscode.commons.util.IOUtil;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.bosh;
|
||||
package org.springframework.ide.vscode.bosh.models;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@@ -15,7 +15,6 @@ import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.ide.vscode.bosh.BoshCommandCloudConfigProviderTest;
|
||||
import org.springframework.ide.vscode.commons.util.IOUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* 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:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.bosh.models;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class CachingModelProviderTest {
|
||||
|
||||
@Test public void goodValuesAreCached() throws Exception {
|
||||
DynamicModelProvider<String> modelProvider = mock(DynamicModelProvider.class);
|
||||
when(modelProvider.getModel(any())).thenReturn("RESULT");
|
||||
|
||||
DynamicModelProvider<String> cached = new CachingModelProvider<>(modelProvider);
|
||||
|
||||
assertEquals("RESULT", cached.getModel(null));
|
||||
assertEquals("RESULT", cached.getModel(null));
|
||||
assertEquals("RESULT", cached.getModel(null));
|
||||
|
||||
verify(modelProvider, times(1)).getModel(any());
|
||||
}
|
||||
|
||||
@Test public void timeoutExceptionsAreCached() throws Exception {
|
||||
DynamicModelProvider<String> modelProvider = mock(DynamicModelProvider.class);
|
||||
when(modelProvider.getModel(any())).thenThrow(new TimeoutException("timed out"));
|
||||
|
||||
DynamicModelProvider<String> cached = new CachingModelProvider<>(modelProvider);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
try {
|
||||
cached.getModel(null);
|
||||
fail("Should have thrown");
|
||||
} catch (Exception _e) {
|
||||
Throwable e = ExceptionUtil.getDeepestCause(_e);
|
||||
assertEquals(TimeoutException.class, e.getClass());
|
||||
}
|
||||
}
|
||||
verify(modelProvider, times(1)).getModel(any());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user