"new style" google pubsub golang 函数无法正常工作

"new style" google pubsub golang functions not working right

我正在尝试使用 Go pubsub library against the local emulated pubsub server。我发现 "old style"(已弃用)函数(例如 CreateSubPullWait)可以找到,但是 "new style" API(例如 IteratorsSubscriptionHandles) 没有按预期工作。

我编写了两个不同的单元测试,它们都测试相同的操作序列,一个使用 "new style" API,一个使用 "old style" API。

顺序是:

https://gist.github.com/ianrose14/db6ecd9ccb6c84c8b36bf49d93b11bfb

使用旧式 API 的测试与我预期的一样:

=== RUN   TestPubSubRereadLegacyForDemo
--- PASS: TestPubSubRereadLegacyForDemo (10.32s)
    pubsubintg_test.go:217: PullWait returned in 21.64236ms (expected 0)
    pubsubintg_test.go:228: PullWait returned in 10.048119558s (expected 10s)
PASS

而使用新式 API 的测试工作不可靠。有时事情会按预期工作:

=== RUN   TestPubSubRereadForDemo
--- PASS: TestPubSubRereadForDemo (11.38s)
    pubsubintg_test.go:149: iter.Next() returned in 17.686701ms (expected 0)
    pubsubintg_test.go:171: iter.Next() returned in 10.059492646s (expected 10s)
PASS

但有时我发现 iter.Stop() 没有及时 return (并注意第二个 iter.Next 比它应该的时间长得多):

=== RUN   TestPubSubRereadForDemo
--- FAIL: TestPubSubRereadForDemo (23.87s)
    pubsubintg_test.go:149: iter.Next() returned in 7.3284ms (expected 0)
    pubsubintg_test.go:171: iter.Next() returned in 20.074994835s (expected 10s)
    pubsubintg_test.go:183: iter.Stop() took too long (2.475055901s)
FAIL

还有一些时候我发现发布消息后的第一个 Pull 时间太长(应该接近即时):

=== RUN   TestPubSubRereadForDemo
--- FAIL: TestPubSubRereadForDemo (6.32s)
    pubsubintg_test.go:147: failed to pull message from iterator: context deadline exceeded
FAIL

有什么想法吗?是否有任何使用新样式 API 的工作示例?不幸的是,Go starter project here 使用旧的、已弃用的 API。

(注意:您的示例输出中的行号似乎与您链接的代码不匹配。)

But sometimes I find that iter.Stop() doesn't return promptly as it should

最近进行了一些更改,修复了调用 iter.Stop 时的过度延迟。如果所有消息都已被确认,它现在应该 return 迅速。尝试同步并再次测试。

(and note how the second iter.Next too way longer than it should):

在您使用新 API 的代码中,您首先从一个空订阅中拉取,使用一个截止时间为 1 秒的上下文。我们称之为 "Pull request A"。虽然底层的 http 请求被取消,但似乎连接没有以服务器尊重的任何方式关闭。因此,就服务器而言,"A" 仍然处于待处理状态。发布后,您立即发出新的拉取请求,我们称之为 "B"。在一条消息通过拉取请求 B return 编辑后,您将消息保持未确认状态,然后发出另一个拉取请求 "C".

现在,当您发布消息时,服务器会将其传送到 "A" 或 "B"。如果它首先将其交付给 "A",您将看到第一个 pull 超过 5s 上下文截止日期。如果它首先发布到 "B",您会看到第一个 pull return 很快,如预期的那样。消息发布到 "B" 且未确认后,服务器会将其重新传送到 "A" 或 "C"。如果它首先选择 "A",那么您最终会花费比预期更长的时间进行第二次拉动。如果它选择 "C",那么您将看到第一次和第二次拉动所花费的时间与您预期的一样长。

如果您不从空订阅中执行初始拉取,您应该会看到您的测试按预期运行。

注意:当您使用旧的 API 时,您看不到任何这些,因为您没有使用旧的 API 执行额外的 "pull from empty subscription" 请求(大概是因为它没有正确支持可取消的上下文)。

旁白:如果您想留下未确认的消息,您应该调用 Message.Done(false)。