uranusjr commented on code in PR #75538:
URL: https://github.com/apache/airflow/pull/75538#discussion_r4490932634


##########
java-sdk/sdk/src/main/kotlin/org/apache/airflow/sdk/execution/Cancellation.kt:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.airflow.sdk.execution
+
+import org.apache.airflow.sdk.Context
+import org.apache.airflow.sdk.StoppableTask
+import sun.misc.Signal
+import sun.misc.SignalHandler
+import java.time.Duration
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicBoolean
+import java.util.concurrent.atomic.AtomicReference
+
+/**
+ * Records whether Airflow has asked the running task to stop. For a 
[StoppableTask], also catches the
+ * signal that carries that request.
+ */
+internal class Cancellation : AutoCloseable {
+  private val claimed = AtomicBoolean()
+  private val requested = CountDownLatch(1)
+  private val signalHandled = CompletableFuture<Unit>()
+
+  @Volatile
+  private var held = false
+
+  @Volatile
+  private var trap: AutoCloseable? = null
+
+  @Volatile
+  private var hook: (() -> Unit)? = null
+
+  fun check(): Boolean {
+    throwIfTaskCannotSeeRequest()
+    return requested.count == 0L
+  }
+
+  fun await(timeout: Duration): Boolean {
+    throwIfTaskCannotSeeRequest()
+    return requested.await(TimeUnit.NANOSECONDS.convert(timeout), 
TimeUnit.NANOSECONDS)
+  }
+
+  private fun throwIfTaskCannotSeeRequest() {
+    check(held) {
+      "Only a StoppableTask can see a stop request. Implement StoppableTask, 
or give an annotated task an @Airflow.OnKill method"
+    }
+  }
+
+  /**
+   * Catches the first stop signal for [task] until [close] is called. The SDK 
calls this method just before it starts the task.
+   *
+   * @throws IllegalStateException if the SDK can catch neither stop signal. 
If the task ran anyway, it would never
+   *   see a stop request, and it could start work, such as a job in an 
external system, that its onKill could not stop.
+   */
+  fun hold(
+    task: StoppableTask,
+    context: Context,
+  ) {
+    val classLoader = Thread.currentThread().contextClassLoader
+    hook = {
+      // On Java 11 and 17, a signal handler thread has no context class 
loader, and libraries can need one.
+      Thread.currentThread().contextClassLoader = classLoader
+      task.onKill(context)
+    }
+    // A signal can reach onKill before trapStopSignals returns. If onKill 
then checks for a stop request,
+    // that check reads held, so set held before calling trapStopSignals.
+    held = true
+    trap =
+      checkNotNull(trapStopSignals(::takeSignal)) {
+        "The SDK cannot catch SIGTERM or SIGINT in this JVM, so the task 
cannot see a stop request. The JVM might run with -Xrs, " +
+          "or without the jdk.unsupported module"
+      }

Review Comment:
   When no signal can be trapped, the task fails with `shouldRetry` from the TI 
context, but the JVM flags won't change between tries. So this should set 
`shouldRetry = false` similar to the constructor failure in Task.



-- 
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]

Reply via email to