|
30 | 30 | import org.opensearch.common.settings.Setting;
|
31 | 31 | import org.opensearch.common.settings.Settings;
|
32 | 32 | import org.opensearch.common.unit.TimeValue;
|
| 33 | +import org.opensearch.core.tasks.TaskCancelledException; |
33 | 34 | import org.opensearch.env.NodeEnvironment;
|
34 | 35 | import org.opensearch.test.OpenSearchTestCase;
|
35 | 36 | import org.junit.Before;
|
@@ -89,6 +90,70 @@ public void setup() {
|
89 | 90 | clusterSettings.registerSetting(DISK_CACHE_ENABLED_SETTING_MAP.get(CacheType.INDICES_REQUEST_CACHE));
|
90 | 91 | }
|
91 | 92 |
|
| 93 | + public void testComputeIfAbsentWhenTheQueryThrowsAnException() throws Exception { |
| 94 | + int onHeapCacheSize = randomIntBetween(10, 30); |
| 95 | + int keyValueSize = 50; |
| 96 | + |
| 97 | + MockCacheRemovalListener<String, String> removalListener = new MockCacheRemovalListener<>(); |
| 98 | + TieredSpilloverCache<String, String> tieredSpilloverCache = initializeTieredSpilloverCache( |
| 99 | + keyValueSize, |
| 100 | + randomIntBetween(1, 4), |
| 101 | + removalListener, |
| 102 | + Settings.builder() |
| 103 | + .put( |
| 104 | + TieredSpilloverCacheSettings.TIERED_SPILLOVER_ONHEAP_STORE_SIZE.getConcreteSettingForNamespace( |
| 105 | + CacheType.INDICES_REQUEST_CACHE.getSettingPrefix() |
| 106 | + ).getKey(), |
| 107 | + onHeapCacheSize * keyValueSize + "b" |
| 108 | + ) |
| 109 | + .build(), |
| 110 | + 0, |
| 111 | + 1 |
| 112 | + ); |
| 113 | + ICacheKey<String> key = getICacheKey(UUID.randomUUID().toString()); |
| 114 | + LoadAwareCacheLoader<ICacheKey<String>, String> tieredCacheLoader = new LoadAwareCacheLoader<>() { |
| 115 | + boolean isLoaded = false; |
| 116 | + |
| 117 | + @Override |
| 118 | + public String load(ICacheKey<String> key) { |
| 119 | + isLoaded = true; |
| 120 | + throw new TaskCancelledException("Query cancelled!"); |
| 121 | + } |
| 122 | + |
| 123 | + @Override |
| 124 | + public boolean isLoaded() { |
| 125 | + return isLoaded; |
| 126 | + } |
| 127 | + }; |
| 128 | + // With this call, we expect an exception from the underlying loader which eventually causes the below call to result into |
| 129 | + // exception. |
| 130 | + try { |
| 131 | + tieredSpilloverCache.computeIfAbsent(key, tieredCacheLoader); |
| 132 | + } catch (Exception ex) { |
| 133 | + assertEquals(TaskCancelledException.class, ex.getCause().getClass()); |
| 134 | + assertEquals("Query cancelled!", ex.getCause().getMessage()); |
| 135 | + } |
| 136 | + // We will call computeIfAbsent again with the same key, but this time the underlying loader should run fine and we should get back |
| 137 | + // the response. |
| 138 | + String expectedRespone = "Cool response!"; |
| 139 | + LoadAwareCacheLoader<ICacheKey<String>, String> tieredCacheLoaderWithNoException = new LoadAwareCacheLoader<>() { |
| 140 | + boolean isLoaded = false; |
| 141 | + |
| 142 | + @Override |
| 143 | + public String load(ICacheKey<String> key) { |
| 144 | + isLoaded = true; |
| 145 | + return expectedRespone; |
| 146 | + } |
| 147 | + |
| 148 | + @Override |
| 149 | + public boolean isLoaded() { |
| 150 | + return isLoaded; |
| 151 | + } |
| 152 | + }; |
| 153 | + String value = tieredSpilloverCache.computeIfAbsent(key, tieredCacheLoaderWithNoException); |
| 154 | + assertEquals(expectedRespone, value); |
| 155 | + } |
| 156 | + |
92 | 157 | public void testComputeIfAbsentWithoutAnyOnHeapCacheEviction() throws Exception {
|
93 | 158 | int onHeapCacheSize = randomIntBetween(10, 30);
|
94 | 159 | int keyValueSize = 50;
|
|
0 commit comments