pvary commented on code in PR #6451:
URL: https://github.com/apache/iceberg/pull/6451#discussion_r1062145905


##########
hive-metastore/src/main/java/org/apache/iceberg/hive/HiveTableOperations.java:
##########
@@ -759,6 +812,98 @@ private static boolean hiveEngineEnabled(TableMetadata 
metadata, Configuration c
         ConfigProperties.ENGINE_HIVE_ENABLED, 
TableProperties.ENGINE_HIVE_ENABLED_DEFAULT);
   }
 
+  @SuppressWarnings("ReverseDnsLookup")
+  private void tryLock(
+      String agentInfo, AtomicReference<Long> lockId, 
AtomicReference<LockState> state)
+      throws UnknownHostException, TException {
+    final LockComponent lockComponent =
+        new LockComponent(LockType.EXCLUSIVE, LockLevel.TABLE, database);
+    lockComponent.setTablename(tableName);
+    final LockRequest lockRequest =
+        new LockRequest(
+            Lists.newArrayList(lockComponent),
+            System.getProperty("user.name"),
+            InetAddress.getLocalHost().getHostName());
+
+    // Only works in Hive 2 or later.
+    if (MetastoreClientVersion.min(MetastoreClientVersion.HIVE_2)) {
+      lockRequest.setAgentInfo(agentInfo);
+    }
+
+    Tasks.foreach(lockRequest)
+        .retry(Integer.MAX_VALUE - 100)
+        .exponentialBackoff(
+            lockCreationMinWaitTime, lockCreationMaxWaitTime, 
lockCreationTimeout, 2.0)
+        .shouldRetryTest(
+            e ->
+                e instanceof TException
+                    && 
MetastoreClientVersion.min(MetastoreClientVersion.HIVE_2))
+        .throwFailureWhenFinished()
+        .run(
+            request -> {
+              try {
+                LockResponse lockResponse = metaClients.run(client -> 
client.lock(request));
+                lockId.set(lockResponse.getLockid());
+                state.set(lockResponse.getState());
+              } catch (TException te) {
+                LOG.warn("Failed to acquire lock {}", request, te);
+                try {
+                  // If we can not check for lock, or we do not find it, then 
rethrow the exception
+                  // Otherwise we are happy as the findLock sets the lockId 
and the state correctly
+                  if 
(!MetastoreClientVersion.min(MetastoreClientVersion.HIVE_2)
+                      || !findLock(agentInfo, lockId, state)) {
+                    throw te;
+                  } else {
+                    LOG.info(
+                        "Found lock by agentInfo {} with id {} and state {}",
+                        agentInfo,
+                        lockId,
+                        state);
+                  }
+                } catch (InterruptedException e) {
+                  Thread.currentThread().interrupt();
+                  LOG.warn(
+                      "Interrupted while checking for lock on table {}.{}", 
database, tableName, e);
+                  throw new RuntimeException("Interrupted while checking for 
lock", e);
+                }
+              } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                LOG.warn("Interrupted while acquiring lock on table {}.{}", 
database, tableName, e);
+                throw new RuntimeException("Interrupted while acquiring lock", 
e);
+              }
+            },
+            TException.class);
+  }
+
+  /**
+   * Search for the locks using HMSClient.showLocks identified by the 
agentInfo. If the lock is
+   * there, then the lockId and the state is set based on the result.
+   *
+   * @param agentInfo The key for searching the locks
+   * @param lockId The lockId if the lock has found
+   * @param state The state if the lock has found
+   * @return <code>true</code> if the the lock is there <code>false</code> if 
the lock is missing
+   */
+  private boolean findLock(
+      String agentInfo, AtomicReference<Long> lockId, 
AtomicReference<LockState> state)
+      throws TException, InterruptedException {
+    ShowLocksRequest showLocksRequest = new ShowLocksRequest();
+    showLocksRequest.setDbname(database);
+    showLocksRequest.setTablename(tableName);
+    ShowLocksResponse response = metaClients.run(client -> 
client.showLocks(showLocksRequest));
+    for (ShowLocksResponseElement lock : response.getLocks()) {
+      if (lock.getAgentInfo().equals(agentInfo)) {

Review Comment:
   Hive 1 has ShowLock, but with a different signature (no agentInfo), which is 
not enough for our purposes. Spark has Hive 1.2 embedded  so the feature is not 
working there.
   
   Also in Hive 1.2 we can not filter the results of the ShowLocks in advance, 
we have to fetch all the locks, and filter them on the client side, which is 
suboptimal for large deployments.
   
   I did not find a suitable solution in Hive 1.2, so I disabled it for now, 
and opted in for using ShowLocks only with newer HMSClients.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to