“新风格”google pubsub golang功能无法正常工作

时间:2016-04-01 20:18:17

标签: go google-cloud-pubsub

我正在尝试对Go pubsub library使用local emulated pubsub server。我发现“旧样式”(已弃用)函数(例如CreateSubPullWait)可以查找,但是“新样式”API(例如Iterators和{{1} })没有按预期工作。

我编写了两个不同的单元测试,它们都测试相同的操作序列,一个使用“新样式”API,另一个使用“旧样式”API。

序列是:

  • 创建订阅
  • 无法提取任何消息(因为没有消息)
  • 发布消息
  • 拉出那条消息,但不要确认
  • 最后再拉一次,这应该需要10秒,因为消息ACK超时必须先到期

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

使用旧式API的测试正如我所期望的那样:

SubscriptionHandles

使用新式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

但有时我发现=== 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.Next的方式太长了):

iter.Stop()

有时我发现发布消息后的第一个Pull需要太长时间(它应该是即时的):

=== 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

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

1 个答案:

答案 0 :(得分:0)

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

  

但有时我发现iter.Stop()没有及时返回,因为它应该

最近发生了一些变化,修复了调用iter时的过度延迟。如果所有消息都已被激活,它现在应该立即返回。尝试同步并再次测试它。

  

(并注意第二个iter.Next如何比它应该更长的时间):

在使用新API的代码中,首先使用带有1s截止日期的上下文从空订阅中提取。我们称之为“拉请求A”。虽然底层的http请求被取消,但似乎连接没有以服务器所遵循的任何方式关闭。因此,就服务器而言,“A”仍处于待定状态。发布后,您立即发出新的拉取请求,我们称之为“B”。在通过拉取请求B返回消息后,您将该消息保留为未包装,并再次发出拉取请求“C”。

现在,当您发布消息时,服务器会将其传递给“A”或“B”。如果它首先将它传递给“A”,您将看到超过5s上下文截止日期的第一次拉动。如果它首先发布到“B”,您将看到第一次快速返回,正如预期的那样。在将消息发布到“B”并且未被取消后,服务器将其重新传送到“A”或“C”。如果它首先选择“A”,那么第二次拉动的时间会超过预期。如果它选择“C”,那么您将看到第一次和第二次拉动的时间与您期望的一样长。

如果您没有从空订阅执行初始拉取,您应该看到您的测试表现得如您所愿。

注意:当您使用旧API时,您没有看到任何此类问题,因为您没有使用旧API执行额外的“从空订阅中提取”请求(可能是因为它不能正确支持可取消的上下文)。

除此之外:如果你想留下一条消息,你应该调用Message.Done(false)。