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