【问题标题】:How to add a timeout to F.Promise.promise() and/or F.Promise.sequence()如何向 F.Promise.promise() 和/或 F.Promise.sequence() 添加超时
【发布时间】:2014-09-23 12:46:57
【问题描述】:

这是我的代码,它有时会超时,因为谷歌有时需要超过 1000 毫秒才能返回。我可能遗漏了一些非常简单的东西,但找不到任何关于如何做到这一点的像样的文档。非常感谢任何帮助!

    final List<F.Promise<List<Event>>> promises = new ArrayList<F.Promise<List<Event>>>();
    F.Promise<List<Event>> primaryCalendar = F.Promise.promise(() -> getEvents(staff,startDate,endDate,"primary",credential));
    promises.add(primaryCalendar);

    for (ExtraCalendar extraCalendar : staff.extraCalendars) {
        promises.add(F.Promise.promise(() -> getEvents(staff, startDate, endDate, extraCalendar.googleCalendarId, credential)));
    }
    F.Promise<List<List<Event>>> events = F.Promise.sequence(promises);
    return events;

我得到的例外是:-

Caused by: java.util.concurrent.TimeoutException: Futures timed out after [1000 milliseconds]
        at scala.concurrent.impl.Promise$DefaultPromise.ready(Promise.scala:219) [scala-library-2.11.2.jar:na]
        at scala.concurrent.impl.Promise$DefaultPromise.result(Promise.scala:223) [scala-library-2.11.2.jar:na]
        at scala.concurrent.Await$$anonfun$result$1.apply(package.scala:116) ~[scala-library-2.11.2.jar:na]
        at akka.dispatch.MonitorableThreadFactory$AkkaForkJoinWorkerThread$$anon$3.block(ThreadPoolBuilder.scala:169) ~[akka-actor_2.11-2.3.4.jar:na]
        at scala.concurrent.forkjoin.ForkJoinPool.managedBlock(ForkJoinPool.java:3640) [scala-library-2.11.2.jar:na]

getEvents 代码按要求在此处,但我认为它不相关(这不是承诺)。

    public static List<Event> getEvents(Staff staff, Date startDate, Date endDate, String googleCalendarId, Credential credential) throws GeneralSecurityException, IOException, NotAuthorizedException {
        com.google.api.services.calendar.Calendar googleClient;
        googleClient = getGoogleClient(credential);
        try {
            if ( Cache.get(getColorCacheKey(staff)) == null ) {
                Colors colors = googleClient.colors().get().execute();
                Cache.set(getColorCacheKey(staff), colors);
            }
            Events events = null;
            DateTime start = new DateTime(startDate);
            DateTime end = new DateTime(endDate);
            // Description might be useful, but it could be big..

            events = googleClient.events().list(googleCalendarId).
                    setFields("items(colorId,summary,end,id,location,start,htmlLink),summary,timeZone").
                    setSingleEvents(true).
                    setTimeMin(start).setTimeMax(end).
                    setMaxResults(1000). // Default 250, max 2500
                    setOrderBy("startTime").
                    execute();
            if ( events.getNextPageToken() != null ) { // This means there are more..  Ignoring for now?
                Logger.warn("events.getNextPageToken() = " + events.getNextPageToken());
            }
            return events.getItems();
        } catch (TokenResponseException | GoogleJsonResponseException e) { // Can happen because they de-authorised?  Or haven't used the site in ages?
            // TODO : Check the exception to see if I can confirm it's really an authError.
            throw new NotAuthorizedException(e);
        }
    }

【问题讨论】:

  • 你能显示getEvents代码吗?
  • 现在在塞勒姆上方。我不认为它是相关的,因为它本身不是一个承诺(只是包装在调用方法中)。我真的只想知道如何设置承诺的超时。 F.Promise.promise() 和 F.Promise.timeout() 都是返回 Promise 的静态调用,所以我不知道如何混合它们?
  • 经过进一步思考,我想我的问题可以简化为如何在返回 Promise 的控制器方法上设置超时,这是 Java 文档似乎不如 Scala 文档的另一个地方。 Scala docs 展示了如何做到这一点,但 Java ones 没有。我如何在 Java 中做 Future.firstCompleted?为什么,哦,为什么 java 文档这么烂:(

标签: playframework playframework-2.0 playframework-2.3


【解决方案1】:

感谢 play google 组中的 Megazord 提供答案。请注意,这不在上述评论中提到的 Java 文档中,但类似的内容在 Scala 文档中。


由于 Play 使用 Akka,您也可以使用它(顺便说一句,大多数时候您需要使用期货和演员,Akka 文档会更好地为您服务)。这是一个如何在 Java 中执行此操作的简单示例:

import play.libs.Akka;
import akka.dispatch.Futures;
import akka.dispatch.MessageDispatcher;
import scala.concurrent.Future;
import scala.concurrent.ExecutionContext;

Future<User> future1 = null;
Future<User> future2 = null;
Future<User> future3 = null;
List<Future<User>> futures = Arrays.asList(future1, future2, future3);

ExecutionContext executor = Akka.system().dispatchers().lookup("your-dispacher-name");
// Or to get the default dispacher
// ExecutionContext executor = Akka.system().dispatcher();

Futures.firstCompletedOf(futures, executor).map( ... );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-03
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 2020-11-10
    相关资源
    最近更新 更多