简体   繁体   English

等待 x 毫秒或直到条件变为真

[英]Wait x milliseconds or until a condition becomes true

I have a code where I send data to our queues and then queue send the acknowledgement back saying they have received the data so I wait for X amount of time before checking whether they have received the data or not.我有一个代码,我将数据发送到我们的队列,然后队列发送回确认,说他们已收到数据,因此我等待 X 时间,然后检查他们是否已收到数据。 Below is the code which does that and it works:下面是执行此操作的代码,并且可以正常工作:

  public boolean send(final long address, final byte[] records, final Socket socket) {
    boolean sent = sendAsync(address, records, socket, true);
    if (sent) {
      try {
        TimeUnit.MILLISECONDS.sleep(800);
      } catch (InterruptedException ex) {
        Thread.currentThread().interrupt();
      }
    }
    // if key is not present, then acknowledgement was received successfully
    sent = !acknowledgementCache.asMap().containsKey(address);
    // and key is still present in the cache, then it means acknowledgment was not received after
    // waiting for timeout period, so we will remove it from cache.
    if (!sent)
      removeFromRetryBucket(address);
    return sent;
  }

Now problem with above code is - I wait for 800 milliseconds no matter what and that is wrong.现在上面代码的问题是 - 无论如何我都等待800 milliseconds ,这是错误的。 It could be possible acknowledgement came back in 100 milliseconds but I still wait for 800 so I want to return as soon as the acknowledgement came back instead of waiting for that X amount of time.确认可能会在 100 毫秒内返回,但我仍然等待 800 毫秒,因此我想在确认返回后立即返回,而不是等待 X 时间。

So I came up with below code which uses awaitility but for some reason it's not working as expected.所以我想出了下面使用等待的代码,但由于某种原因它没有按预期工作。 Meaning, even though acknowledgement came back fast, it still timeout.意思是,即使确认很快返回,它仍然超时。 I tried increasing value of timeout to very high number as well and still it times out so something is wrong looks like.我也尝试将超时值增加到非常高的值,但它仍然超时,所以看起来有些问题。 Is there any better way to do this?有没有更好的方法来做到这一点?

  public boolean send(final long address, final byte[] records, final Socket socket) {
    boolean sent = sendAsync(address, records, socket, true);
    if (sent) {
      try {
        // if key is not present, then acknowledgement was received successfully
        Awaitility.await().atMost(800, TimeUnit.MILLISECONDS)
            .untilTrue(new AtomicBoolean(!acknowledgementCache.asMap().containsKey(address)));
        return true;
      } catch (ConditionTimeoutException ex) {
      }
    }
    // and key is still present in the cache, then it means acknowledgment was not received after
    // waiting for timeout period, so we will remove it from cache.
    removeFromRetryBucket(address);
    return false;
  }

Note: I am working with Java 7 as of now.注意:我现在正在使用 Java 7。 I do have access to Guava so if anything better is there other than awaitility then I can use that as well.我确实可以访问番石榴,所以如果除了等待之外还有更好的东西,那么我也可以使用它。

To be able to check that in Java 7 you need to write a callable.为了能够在 Java 7 中进行检查,您需要编写一个可调用的。

@Test
public void send() {
    //when
    boolean sent = sendAsync(address, records, socket, true);
    //then
    if (sent) {
        await().until(receivedPackageCount(), equalTo(false));
    }
}

private Callable receivedPackageCount(String address) {
    return new Callable() {
        @Override
        public boolean call() throws Exception {
            return acknowledgementCache.asMap().containsKey(address);
        }
    };
}

It must be something similar above.它必须与上面类似。 There can be compilation errors because I wrote it without ide.可能会出现编译错误,因为我在没有 ide 的情况下编写了它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM