Skip to content

Commit 68faedc

Browse files
committed
HBASE-23898 Add trace support for simple apis in async client (#2813)
Signed-off-by: Guanghao Zhang <zghao@apache.org>
1 parent 1f4ddbf commit 68faedc

16 files changed

Lines changed: 1169 additions & 346 deletions

File tree

hbase-client/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,16 @@
144144
<groupId>org.jruby.joni</groupId>
145145
<artifactId>joni</artifactId>
146146
</dependency>
147+
<dependency>
148+
<groupId>io.opentelemetry</groupId>
149+
<artifactId>opentelemetry-sdk</artifactId>
150+
<scope>test</scope>
151+
</dependency>
152+
<dependency>
153+
<groupId>io.opentelemetry</groupId>
154+
<artifactId>opentelemetry-sdk-testing</artifactId>
155+
<scope>test</scope>
156+
</dependency>
147157
<dependency>
148158
<groupId>org.slf4j</groupId>
149159
<artifactId>jcl-over-slf4j</artifactId>

hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncConnection.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ public interface AsyncConnection extends Closeable {
6464
/**
6565
* Retrieve an {@link AsyncTable} implementation for accessing a table.
6666
* <p>
67-
* The returned instance will use default configs. Use {@link #getTableBuilder(TableName)} if
68-
* you want to customize some configs.
67+
* The returned instance will use default configs. Use {@link #getTableBuilder(TableName)} if you
68+
* want to customize some configs.
6969
* <p>
7070
* This method no longer checks table existence. An exception will be thrown if the table does not
7171
* exist only when the first operation is attempted.

hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncConnectionImpl.java

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import static org.apache.hadoop.hbase.client.NonceGenerator.CLIENT_NONCES_ENABLED_KEY;
2828
import static org.apache.hadoop.hbase.util.FutureUtils.addListener;
2929

30+
import io.opentelemetry.api.trace.Span;
31+
import io.opentelemetry.context.Scope;
3032
import java.io.IOException;
3133
import java.net.SocketAddress;
3234
import java.util.Optional;
@@ -51,6 +53,7 @@
5153
import org.apache.hadoop.hbase.ipc.RpcClientFactory;
5254
import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
5355
import org.apache.hadoop.hbase.security.User;
56+
import org.apache.hadoop.hbase.trace.TraceUtil;
5457
import org.apache.hadoop.hbase.util.ConcurrentMapUtils;
5558
import org.apache.hadoop.hbase.util.Threads;
5659
import org.apache.hadoop.security.UserGroupInformation;
@@ -121,7 +124,7 @@ class AsyncConnectionImpl implements AsyncConnection {
121124
private volatile ConnectionOverAsyncConnection conn;
122125

123126
public AsyncConnectionImpl(Configuration conf, ConnectionRegistry registry, String clusterId,
124-
SocketAddress localAddress, User user) {
127+
SocketAddress localAddress, User user) {
125128
this.conf = conf;
126129
this.user = user;
127130

@@ -135,8 +138,8 @@ public AsyncConnectionImpl(Configuration conf, ConnectionRegistry registry, Stri
135138
} else {
136139
this.metrics = Optional.empty();
137140
}
138-
this.rpcClient = RpcClientFactory.createClient(
139-
conf, clusterId, localAddress, metrics.orElse(null));
141+
this.rpcClient =
142+
RpcClientFactory.createClient(conf, clusterId, localAddress, metrics.orElse(null));
140143
this.rpcControllerFactory = RpcControllerFactory.instantiate(conf);
141144
this.rpcTimeout =
142145
(int) Math.min(Integer.MAX_VALUE, TimeUnit.NANOSECONDS.toMillis(connConf.getRpcTimeoutNs()));
@@ -159,14 +162,13 @@ public AsyncConnectionImpl(Configuration conf, ConnectionRegistry registry, Stri
159162
LOG.warn("{} is true, but {} is not set", STATUS_PUBLISHED, STATUS_LISTENER_CLASS);
160163
} else {
161164
try {
162-
listener = new ClusterStatusListener(
163-
new ClusterStatusListener.DeadServerHandler() {
164-
@Override
165-
public void newDead(ServerName sn) {
166-
locator.clearCache(sn);
167-
rpcClient.cancelConnections(sn);
168-
}
169-
}, conf, listenerClass);
165+
listener = new ClusterStatusListener(new ClusterStatusListener.DeadServerHandler() {
166+
@Override
167+
public void newDead(ServerName sn) {
168+
locator.clearCache(sn);
169+
rpcClient.cancelConnections(sn);
170+
}
171+
}, conf, listenerClass);
170172
} catch (IOException e) {
171173
LOG.warn("Failed create of ClusterStatusListener, not a critical, ignoring...", e);
172174
}
@@ -206,28 +208,30 @@ public boolean isClosed() {
206208

207209
@Override
208210
public void close() {
209-
if (!closed.compareAndSet(false, true)) {
210-
return;
211-
}
212-
LOG.info("Connection has been closed by {}.", Thread.currentThread().getName());
213-
if(LOG.isDebugEnabled()){
214-
logCallStack(Thread.currentThread().getStackTrace());
215-
}
216-
IOUtils.closeQuietly(clusterStatusListener,
217-
e -> LOG.warn("failed to close clusterStatusListener", e));
218-
IOUtils.closeQuietly(rpcClient, e -> LOG.warn("failed to close rpcClient", e));
219-
IOUtils.closeQuietly(registry, e -> LOG.warn("failed to close registry", e));
220-
synchronized (this) {
221-
if (choreService != null) {
222-
choreService.shutdown();
223-
choreService = null;
211+
TraceUtil.trace(() -> {
212+
if (!closed.compareAndSet(false, true)) {
213+
return;
224214
}
225-
}
226-
metrics.ifPresent(MetricsConnection::shutdown);
227-
ConnectionOverAsyncConnection c = this.conn;
228-
if (c != null) {
229-
c.closePool();
230-
}
215+
LOG.info("Connection has been closed by {}.", Thread.currentThread().getName());
216+
if (LOG.isDebugEnabled()) {
217+
logCallStack(Thread.currentThread().getStackTrace());
218+
}
219+
IOUtils.closeQuietly(clusterStatusListener,
220+
e -> LOG.warn("failed to close clusterStatusListener", e));
221+
IOUtils.closeQuietly(rpcClient, e -> LOG.warn("failed to close rpcClient", e));
222+
IOUtils.closeQuietly(registry, e -> LOG.warn("failed to close registry", e));
223+
synchronized (this) {
224+
if (choreService != null) {
225+
choreService.shutdown();
226+
choreService = null;
227+
}
228+
}
229+
metrics.ifPresent(MetricsConnection::shutdown);
230+
ConnectionOverAsyncConnection c = this.conn;
231+
if (c != null) {
232+
c.closePool();
233+
}
234+
}, "AsyncConnection.close");
231235
}
232236

233237
private void logCallStack(StackTraceElement[] stackTraceElements) {
@@ -341,7 +345,7 @@ public AsyncTable<AdvancedScanResultConsumer> build() {
341345

342346
@Override
343347
public AsyncTableBuilder<ScanResultConsumer> getTableBuilder(TableName tableName,
344-
ExecutorService pool) {
348+
ExecutorService pool) {
345349
return new AsyncTableBuilderBase<ScanResultConsumer>(tableName, connConf) {
346350

347351
@Override
@@ -382,7 +386,7 @@ public AsyncBufferedMutatorBuilder getBufferedMutatorBuilder(TableName tableName
382386

383387
@Override
384388
public AsyncBufferedMutatorBuilder getBufferedMutatorBuilder(TableName tableName,
385-
ExecutorService pool) {
389+
ExecutorService pool) {
386390
return new AsyncBufferedMutatorBuilderImpl(connConf, getTableBuilder(tableName, pool),
387391
RETRY_TIMER);
388392
}
@@ -406,28 +410,36 @@ public Connection toConnection() {
406410

407411
@Override
408412
public CompletableFuture<Hbck> getHbck() {
409-
CompletableFuture<Hbck> future = new CompletableFuture<>();
410-
addListener(registry.getActiveMaster(), (sn, error) -> {
411-
if (error != null) {
412-
future.completeExceptionally(error);
413-
} else {
414-
try {
415-
future.complete(getHbck(sn));
416-
} catch (IOException e) {
417-
future.completeExceptionally(e);
413+
return TraceUtil.tracedFuture(() -> {
414+
CompletableFuture<Hbck> future = new CompletableFuture<>();
415+
addListener(registry.getActiveMaster(), (sn, error) -> {
416+
if (error != null) {
417+
future.completeExceptionally(error);
418+
} else {
419+
try {
420+
future.complete(getHbck(sn));
421+
} catch (IOException e) {
422+
future.completeExceptionally(e);
423+
}
418424
}
419-
}
420-
});
421-
return future;
425+
});
426+
return future;
427+
}, getClass().getName() + ".getHbck");
422428
}
423429

424430
@Override
425431
public Hbck getHbck(ServerName masterServer) throws IOException {
426-
// we will not create a new connection when creating a new protobuf stub, and for hbck there
427-
// will be no performance consideration, so for simplification we will create a new stub every
428-
// time instead of caching the stub here.
429-
return new HBaseHbck(MasterProtos.HbckService.newBlockingStub(
430-
rpcClient.createBlockingRpcChannel(masterServer, user, rpcTimeout)), rpcControllerFactory);
432+
Span span = TraceUtil.createSpan(getClass().getName() + ".getHbck")
433+
.setAttribute(TraceUtil.SERVER_NAME_KEY, masterServer.getServerName());
434+
try (Scope scope = span.makeCurrent()) {
435+
// we will not create a new connection when creating a new protobuf stub, and for hbck there
436+
// will be no performance consideration, so for simplification we will create a new stub every
437+
// time instead of caching the stub here.
438+
return new HBaseHbck(
439+
MasterProtos.HbckService
440+
.newBlockingStub(rpcClient.createBlockingRpcChannel(masterServer, user, rpcTimeout)),
441+
rpcControllerFactory);
442+
}
431443
}
432444

433445
Optional<MetricsConnection> getConnectionMetrics() {

0 commit comments

Comments
 (0)