首页 > 解决方案 > toCompletableFuture() 卡住异步缓存

问题描述

您好,我试图强制终止承诺以从中获得结果,但它只是卡在加载中。

public class CacheController extends Controller {
    private AsyncCacheApi cache;
    public Result cache()
    {
        String test = "nice";
        cache.set("item.key", test, 15);

        Customer user = new Customer("Ana", 12);
        CompletionStage<Done> result = cache.set(user.getName(), user);
        block(result);

        return ok("Cached");
    }
    public Result checkCache() throws Exception
    {
        Logger.info("start");
        //CompletionStage<String> news = cache.get("item.key");
        //news.thenRun(() -> System.out.println("works"));

        CompletionStage<Customer> result = cache.get("Ana");

        Logger.info("step 1");

        Logger.info(cache.get("Ana").toString());
        Logger.info("Step 2");

        Customer c = block(result);

        Logger.info("Step 3 " + c.getName());

        //result.thenRun(() -> setUser(result)).thenRun(() -> Logger.info(user.getName() + " " + user.getAge()));


        return ok("cancan");
    }

    private <T> T block(CompletionStage<T> stage) {
        try {
            return stage.toCompletableFuture().get();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }
}

尝试加载页面时,我猜测它在第 2 步之后卡住了line 56: Customer c = block(result);有什么想法可以解决吗?

标签: asynchronouscachingplayframework-2.6

解决方案


@科德林

我有同样的问题。但是,请参阅https://www.playframework.com/documentation/2.6.x/JavaCache#Setting-the-execution-context

默认情况下,所有 Ehcache 操作都是阻塞的,异步实现会阻塞默认执行上下文中的线程。

也许 CompletableFuture.get() 卡住了,因为它与调用者在同一个线程中执行。

参考链接的页面,我在 application.conf 中添加了下面的代码段,它起作用了。

play.cache.dispatcher = "contexts.blockingCacheDispatcher"

contexts {
blockingCacheDispatcher {
    fork-join-executor {
    parallelism-factor = 3.0
    }
  }
}

推荐阅读