You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@linkis.apache.org by pe...@apache.org on 2022/09/16 03:05:45 UTC
[incubator-linkis] branch dev-1.3.1 updated: feat(common): remove use of sun.misc.Signal (#3337)
This is an automated email from the ASF dual-hosted git repository.
peacewong pushed a commit to branch dev-1.3.1
in repository https://gitbox.apache.org/repos/asf/incubator-linkis.git
The following commit(s) were added to refs/heads/dev-1.3.1 by this push:
new b804c971e feat(common): remove use of sun.misc.Signal (#3337)
b804c971e is described below
commit b804c971e1954a384753a6cd63ba8655c3cb5265
Author: Jack Xu <xu...@126.com>
AuthorDate: Fri Sep 16 11:05:40 2022 +0800
feat(common): remove use of sun.misc.Signal (#3337)
* feat(common): remove use of sun.misc.Signal
---
.../linkis/common/utils/ShutdownHookManager.scala | 139 +++++++++++++++++++++
.../apache/linkis/common/utils/ShutdownUtils.scala | 87 -------------
.../org/apache/linkis/common/utils/Utils.scala | 2 +-
3 files changed, 140 insertions(+), 88 deletions(-)
diff --git a/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/ShutdownHookManager.scala b/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/ShutdownHookManager.scala
new file mode 100644
index 000000000..ace2973e6
--- /dev/null
+++ b/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/ShutdownHookManager.scala
@@ -0,0 +1,139 @@
+/*
+ * 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.linkis.common.utils
+
+import java.util.PriorityQueue
+
+import org.slf4j.{Logger, LoggerFactory}
+
+private[linkis] object ShutdownHookManager {
+
+ val DEFAULT_SHUTDOWN_ORDER: Int = Int.MaxValue
+
+ private lazy val shutdownHooks = {
+ val manager = new LinkisShutdownHookManager()
+ manager.install()
+ manager
+ }
+
+ /**
+ * This detects whether the JVM is shutting down by Runtime#addShutdownHook throwing an
+ * IllegalStateException.
+ */
+ def inShutdown(): Boolean = {
+ try {
+ val hook = new Thread {
+ override def run(): Unit = {}
+ }
+ // scalastyle:off runtimeaddshutdownhook
+ Runtime.getRuntime.addShutdownHook(hook)
+ // scalastyle:on runtimeaddshutdownhook
+ Runtime.getRuntime.removeShutdownHook(hook)
+ } catch {
+ case _: IllegalStateException => return true
+ }
+ false
+ }
+
+ /**
+ * Adds a shutdown hook with default order.
+ *
+ * @param hook
+ * The code to run during shutdown.
+ * @return
+ * A handle that can be used to unregister the shutdown hook.
+ */
+ def addShutdownHook(hook: => Unit): LinkisShutdownHook = {
+ addShutdownHook(DEFAULT_SHUTDOWN_ORDER)(hook)
+ }
+
+ /**
+ * Adds a shutdown hook with the given order. Hooks with lower order values run first.
+ *
+ * @param hook
+ * The code to run during shutdown.
+ * @return
+ * A handle that can be used to unregister the shutdown hook.
+ */
+ def addShutdownHook(order: Int)(hook: => Unit): LinkisShutdownHook = {
+ shutdownHooks.add(order, hook)
+ }
+
+ /**
+ * Remove a previously installed shutdown hook.
+ *
+ * @param ref
+ * A handle returned by `addShutdownHook`.
+ * @return
+ * Whether the hook was removed.
+ */
+ def removeShutdownHook(ref: LinkisShutdownHook): Boolean = {
+ shutdownHooks.remove(ref)
+ }
+
+}
+
+private[utils] class LinkisShutdownHookManager {
+
+ private val hooks = new PriorityQueue[LinkisShutdownHook]()
+ @volatile private var shuttingDown = false
+
+ implicit val logger: Logger = LoggerFactory.getLogger(classOf[LinkisShutdownHookManager])
+
+ def install(): Unit = {
+ val hookTask = new Runnable() {
+ override def run(): Unit = runAll()
+ }
+ // scalastyle:off runtimeaddshutdownhook
+ Runtime.getRuntime.addShutdownHook(new Thread(hookTask))
+ // scalastyle:on runtimeaddshutdownhook
+ }
+
+ def runAll(): Unit = {
+ shuttingDown = true
+ var nextHook: LinkisShutdownHook = null
+ while ({ nextHook = hooks.synchronized { hooks.poll() }; nextHook != null }) {
+ Utils.tryAndWarn(nextHook.run())
+ }
+ }
+
+ def add(order: Int, hook: => Unit): LinkisShutdownHook = {
+ hooks.synchronized {
+ if (shuttingDown) {
+ throw new IllegalStateException("Shutdown hooks cannot be modified during shutdown.")
+ }
+ val hookRef = new LinkisShutdownHook(order, hook)
+ hooks.add(hookRef)
+ hookRef
+ }
+ }
+
+ def remove(ref: LinkisShutdownHook): Boolean = {
+ hooks.synchronized { hooks.remove(ref) }
+ }
+
+}
+
+private[linkis] class LinkisShutdownHook(private val priority: Int, hook: => Unit)
+ extends Comparable[LinkisShutdownHook] {
+
+ override def compareTo(other: LinkisShutdownHook): Int = priority.compareTo(other.priority)
+
+ def run(): Unit = hook
+
+}
diff --git a/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/ShutdownUtils.scala b/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/ShutdownUtils.scala
deleted file mode 100644
index 7fefb16ab..000000000
--- a/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/ShutdownUtils.scala
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.linkis.common.utils
-
-import scala.collection.mutable.ArrayBuffer
-
-import sun.misc.{Signal, SignalHandler}
-
-object ShutdownUtils {
-
- private val shutdownRunners = ArrayBuffer[ShutdownRunner]()
-
- def addShutdownHook(runnable: Runnable): Unit = addShutdownHook(Int.MaxValue, runnable)
-
- def addShutdownHook(order: Int, runnable: Runnable): Unit =
- shutdownRunners synchronized shutdownRunners += new DefaultShutdownRunner(order, runnable)
-
- def addShutdownHook(hook: => Unit): Unit = addShutdownHook(Int.MaxValue, hook)
-
- def addShutdownHook(order: Int, hook: => Unit): Unit =
- shutdownRunners synchronized shutdownRunners += new FunctionShutdownRunner(order, hook)
-
- def addShutdownHook(shutdownRunner: ShutdownRunner): Unit =
- shutdownRunners synchronized shutdownRunners += shutdownRunner
-
- private val signals = Array("TERM", "HUP", "INT")
- .map(signal => Utils.tryQuietly(new Signal(signal)))
- .filter(_ != null)
-
- private val signalHandler = new SignalHandler {
-
- override def handle(signal: Signal): Unit = {
- val hooks = shutdownRunners.sortBy(_.order).toArray.map {
- case m: DefaultShutdownRunner =>
- Utils.defaultScheduler.execute(m)
- m
- case m =>
- val runnable = new DefaultShutdownRunner(m.order, m)
- Utils.defaultScheduler.execute(runnable)
- runnable
- }
- val startTime = System.currentTimeMillis
- ShutdownUtils synchronized {
- while (System.currentTimeMillis - startTime < 30000 && hooks.exists(!_.isCompleted))
- ShutdownUtils.wait(3000)
- }
- System.exit(0)
- }
-
- }
-
- signals.foreach(Signal.handle(_, signalHandler))
-}
-
-trait ShutdownRunner extends Runnable {
- val order: Int
-}
-
-class DefaultShutdownRunner(override val order: Int, runnable: Runnable) extends ShutdownRunner {
- private var completed = false
-
- override def run(): Unit = Utils.tryFinally(runnable.run()) {
- completed = true
- ShutdownUtils synchronized ShutdownUtils.notify()
- }
-
- def isCompleted: Boolean = completed
-}
-
-class FunctionShutdownRunner(override val order: Int, hook: => Unit) extends ShutdownRunner {
- override def run(): Unit = hook
-}
diff --git a/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/Utils.scala b/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/Utils.scala
index 6a7a030fd..5f2361f48 100644
--- a/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/Utils.scala
+++ b/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/Utils.scala
@@ -322,7 +322,7 @@ object Utils extends Logging {
lines.mkString("\n")
}
- def addShutdownHook(hook: => Unit): Unit = ShutdownUtils.addShutdownHook(hook)
+ def addShutdownHook(hook: => Unit): Unit = ShutdownHookManager.addShutdownHook(hook)
def getClassInstance[T](className: String): T = {
Utils.tryThrow(
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@linkis.apache.org
For additional commands, e-mail: commits-help@linkis.apache.org