我正在尝试对Go pubsub library使用local emulated pubsub server。我发现“旧样式”(已弃用)函数(例如CreateSub
和PullWait
)可以查找,但是“新样式”API(例如Iterators
和{{1} })没有按预期工作。
我编写了两个不同的单元测试,它们都测试相同的操作序列,一个使用“新样式”API,另一个使用“旧样式”API。
序列是:
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。
答案 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)。