【问题标题】:How to wait until Spark service is stopped?如何等到 Spark 服务停止?
【发布时间】:2019-12-12 17:13:53
【问题描述】:

对于我的 Spark API,我正在构建集成测试。有时我想停止并启动 Spark 实例。当我这样做时,我有时会遇到一个问题,即我正在创建一个新的 Spark 实例,而旧的实例仍在一个单独的线程上关闭。了解 Spark 实例何时真正关闭会很有帮助。

首先我像这样启动我的 Spark 实例:

Spark.init();
Spark.awaitInitialization();

然后我就这样停止了:

Spark.stop();

现在我打电话给stop() 后,Spark 服务并没有真正停止!

是否有与awaitInitialization() 类似的功能或知道 Spark 服务何时实际停止的其他方式?

【问题讨论】:

标签: java spark-java


【解决方案1】:

Spark 2.8.0 引入了awaitStop() 方法:https://github.com/perwendel/spark/pull/730

如果您卡在以下版本(例如,使用使用 Spark 2.6.0 的 spark-kotlin),您可以使用一些反射来识别 Spark 的当前状态:

    fun awaitShutdown() {
        Spark.stop()

        while (isSparkInitialized()) {
            Thread.sleep(100)
        }
    }

    /**
     * Access the internals of Spark to check if the "initialized" flag is already set to false.
     */
    private fun isSparkInitialized(): Boolean {
        val sparkClass = Spark::class.java
        val getInstanceMethod = sparkClass.getDeclaredMethod("getInstance")
        getInstanceMethod.isAccessible = true
        val service = getInstanceMethod.invoke(null) as Service

        val serviceClass = service::class.java
        val initializedField = serviceClass.getDeclaredField("initialized")
        initializedField.isAccessible = true
        val initialized = initializedField.getBoolean(service)

        return initialized
    }

(摘自https://github.com/debuglevel/sparkmicroserviceutils/blob/ec6b9692d808ecc448f1828f5487739101a2f62e/src/main/kotlin/de/debuglevel/microservices/utils/spark/SparkTestUtils.kt

【讨论】:

  • 澄清一下——2.8.0中引入的方法叫做awaitStop(),而不是awaitShutdown()
【解决方案2】:

我在https://github.com/perwendel/spark/issues/731 中阅读了这个解决方案并为我工作:

public static void stopServer() {
        try {
            Spark.stop();
            while (true) {
                try {
                    Spark.port();
                    Thread.sleep(500);
                } catch (final IllegalStateException ignored) {
                    break;
                }
            }
        } catch (final Exception ex) {
            // Ignore
        }
    }

【讨论】:

    【解决方案3】:

    我使用 spark-java 为集成/功能测试构建模拟服务。

    我的测试拆解代码:

    public FakeServer shutdown() {
        service.stop();
        // Remove when https://github.com/perwendel/spark/issues/705 is fixed.
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return this;
    }
    

    对我来说无缝工作,每个测试都会设置 FakeServer @Before 并在测试完成时将其拆除 - @After。

    试一试。

    【讨论】:

      猜你喜欢
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-02
      • 2017-03-17
      • 1970-01-01
      相关资源
      最近更新 更多