1 package com.atlassian.vcache.internal.core.service;
2
3 import com.atlassian.marshalling.api.MarshallingException;
4 import com.atlassian.vcache.ExternalCache;
5 import com.atlassian.vcache.ExternalCacheException;
6 import com.atlassian.vcache.internal.ExternalCacheExceptionListener;
7 import com.atlassian.vcache.internal.core.VCacheCoreUtils;
8 import org.slf4j.Logger;
9
10 import java.time.Duration;
11 import java.util.concurrent.Callable;
12 import java.util.concurrent.CompletableFuture;
13 import java.util.concurrent.CompletionStage;
14 import java.util.concurrent.ExecutionException;
15 import java.util.function.Consumer;
16
17 import static com.atlassian.vcache.ExternalCacheException.Reason.MARSHALLER_FAILURE;
18 import static com.atlassian.vcache.ExternalCacheException.Reason.UNCLASSIFIED_FAILURE;
19 import static com.atlassian.vcache.internal.NameValidator.requireValidCacheName;
20 import static com.atlassian.vcache.internal.core.VCacheCoreUtils.failed;
21 import static java.util.Objects.requireNonNull;
22
23
24
25
26
27
28
29 public abstract class AbstractExternalCache<V> implements ExternalCache<V> {
30 protected final String name;
31 protected final Duration lockTimeout;
32 private ExternalCacheExceptionListener externalCacheExceptionListener;
33
34 protected AbstractExternalCache(String name,
35 Duration lockTimeout,
36 ExternalCacheExceptionListener externalCacheExceptionListener) {
37 this.name = requireValidCacheName(name);
38 this.lockTimeout = requireNonNull(lockTimeout);
39 this.externalCacheExceptionListener = requireNonNull(externalCacheExceptionListener);
40 }
41
42
43
44
45
46
47 protected abstract AbstractExternalCacheRequestContext<V> ensureCacheContext();
48
49
50
51
52
53
54 protected abstract Logger getLogger();
55
56
57
58
59 protected abstract ExternalCacheException mapException(Exception ex);
60
61 @Override
62 public final String getName() {
63 return name;
64 }
65
66
67
68
69
70
71
72
73 protected <T> CompletionStage<T> perform(Callable<T> txn) {
74 return perform(txn, (i) -> {
75 });
76 }
77
78
79
80
81
82
83
84
85
86 protected <T> CompletionStage<T> perform(Callable<T> txn, Consumer<T> successHandler) {
87 final ExternalCacheException exception;
88 try {
89 final T outcome = txn.call();
90 successHandler.accept(outcome);
91 return VCacheCoreUtils.successful(outcome);
92 } catch (MarshallingException ex) {
93 exception = new ExternalCacheException(MARSHALLER_FAILURE, ex);
94 } catch (ExecutionException | InterruptedException ex) {
95 exception = new ExternalCacheException(UNCLASSIFIED_FAILURE, ex);
96 } catch (ExternalCacheException ece) {
97 exception = ece;
98 } catch (Exception ex) {
99 exception = mapException(ex);
100 }
101
102 externalCacheExceptionListener.onThrow(getName(), exception);
103 return failed(new CompletableFuture<>(), exception);
104 }
105 }