-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathAtomixChannel.java
More file actions
134 lines (113 loc) · 4.18 KB
/
Copy pathAtomixChannel.java
File metadata and controls
134 lines (113 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package io.atomix;
import io.atomix.util.concurrent.Threads;
import io.grpc.CallOptions;
import io.grpc.ClientCall;
import io.grpc.LoadBalancerProvider;
import io.grpc.LoadBalancerRegistry;
import io.grpc.ManagedChannel;
import io.grpc.MethodDescriptor;
import io.grpc.NameResolverProvider;
import io.grpc.NameResolverRegistry;
import io.grpc.internal.DnsNameResolverProvider;
import io.grpc.internal.PickFirstLoadBalancerProvider;
import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* gRPC {@link io.grpc.Channel} for Atomix primitives.
*/
public class AtomixChannel extends ManagedChannel {
private static final Logger LOGGER = LoggerFactory.getLogger(AtomixChannel.class);
private static final String DEFAULT_HOST = "localhost";
private static final int DEFAULT_PORT = 5678;
private static final LoadBalancerProvider PICK_FIRST_LOAD_BALANCER_PROVIDER = new PickFirstLoadBalancerProvider();
private static final NameResolverProvider DNS_NAME_RESOLVER_PROVIDER = new DnsNameResolverProvider();
static {
LoadBalancerRegistry.getDefaultRegistry()
.register(PICK_FIRST_LOAD_BALANCER_PROVIDER);
NameResolverRegistry.getDefaultRegistry()
.register(DNS_NAME_RESOLVER_PROVIDER);
}
private static volatile AtomixChannel instance;
/**
* Returns the singleton {@link AtomixChannel} instance for use in Kubernetes pods.
*
* @return the singleton instance
*/
public static AtomixChannel instance() {
if (instance == null) {
synchronized (AtomixChannel.class) {
if (instance == null) {
instance = new AtomixChannel();
}
}
}
return instance;
}
private final ManagedChannel parent;
private final ScheduledExecutorService executorService;
public AtomixChannel() {
this(DEFAULT_HOST, DEFAULT_PORT);
}
public AtomixChannel(int port) {
this(DEFAULT_HOST, port);
}
public AtomixChannel(String host, int port) {
this(buildChannel(host, port));
}
public AtomixChannel(ManagedChannel channel) {
this(channel, Executors.newScheduledThreadPool(
Runtime.getRuntime().availableProcessors() * 2,
Threads.namedThreads("atomix-channel-%d", LOGGER)));
}
private AtomixChannel(ManagedChannel parent, ScheduledExecutorService executorService) {
this.parent = parent;
this.executorService = executorService;
}
private static ManagedChannel buildChannel(String host, int port) {
return NettyChannelBuilder.forAddress(host, port)
.usePlaintext()
.enableRetry()
.nameResolverFactory(DNS_NAME_RESOLVER_PROVIDER)
.defaultLoadBalancingPolicy(PICK_FIRST_LOAD_BALANCER_PROVIDER.getPolicyName())
.build();
}
@Override
public <RequestT, ResponseT> ClientCall<RequestT, ResponseT> newCall(MethodDescriptor<RequestT, ResponseT> methodDescriptor, CallOptions callOptions) {
return parent.newCall(methodDescriptor, callOptions);
}
@Override
public String authority() {
return parent.authority();
}
public ScheduledExecutorService executor() {
return executorService;
}
@Override
public ManagedChannel shutdown() {
parent.shutdown();
executorService.shutdown();
return this;
}
@Override
public boolean isShutdown() {
return parent.isShutdown() && executorService.isShutdown();
}
@Override
public boolean isTerminated() {
return parent.isTerminated() && executorService.isTerminated();
}
@Override
public ManagedChannel shutdownNow() {
parent.shutdownNow();
executorService.shutdownNow();
return this;
}
@Override
public boolean awaitTermination(long timeout, TimeUnit timeUnit) throws InterruptedException {
return parent.awaitTermination(timeout, timeUnit) && executorService.awaitTermination(timeout, timeUnit);
}
}