在某些事件(即gs.up.receive
和as.up.receive
)中的相关ID是重复的。
ttn-lw-cli events subscribe --gateway-id ...
例如:
{
"name": "gs.up.receive",
"time": "2019-05-10T08:48:36.397803Z",
"identifiers": [
{
"gateway_ids": {
"gateway_id": "tektelic-micro",
"eui": "647FDAFFFE0059AB"
}
}
],
"data": {
"@type": "type.googleapis.com/ttn.lorawan.v3.UplinkMessage",
"raw_payload": "QKogASYAkdgBU2NToyoatD/C",
"settings": {
"data_rate": {
"lora": {
"bandwidth": 125000,
"spreading_factor": 7
}
},
"coding_rate": "4/5",
"frequency": "867900000",
"timestamp": 3375161699
},
"rx_metadata": [
{
"gateway_ids": {
"gateway_id": "tektelic-micro",
"eui": "647FDAFFFE0059AB"
},
"timestamp": 3375161699,
"rssi": 2,
"snr": 10,
"uplink_token": "ChwKGgoOdGVrdGVsaWMtbWljcm8SCGR/2v/+AFmrEOPCs8kM"
}
],
"received_at": "2019-05-10T08:48:36.397329Z",
"correlation_ids": [
"gs:conn:01DAGEFV4TBH5K9AVAX86NPDXM",
"gs:uplink:01DAGEW31DQZQNSCQPJ28KGFMF"
],
"gateway_channel_index": 4
},
"correlation_ids": [
"gs:conn:01DAGEFV4TBH5K9AVAX86NPDXM",
"gs:uplink:01DAGEW31DQZQNSCQPJ28KGFMF",
"gs:conn:01DAGEFV4TBH5K9AVAX86NPDXM",
"gs:uplink:01DAGEW31DQZQNSCQPJ28KGFMF"
],
"origin": "Johans-MacBook-Pro.local"
}
correlation_ids
没有重复项
相关ID可能会添加两次。 这可能在事件包中,其中在上下文中添加了相关ID。
是的
@htdvisser ,问题似乎是来自事件有效负载的相关ID附加到上下文的ID上,即,如果您有此ID;
ctx := events.ContextWithCorrelationID(ctx, fmt.Sprintf("gs:uplink:%s", events.NewCorrelationID()))
msg.CorrelationIDs = append(msg.CorrelationIDs, events.CorrelationIDsFromContext(ctx)...)
registerReceiveUplink(ctx, conn.Gateway(), msg)
在事件中,相关ID是重复的,因为它们都在ctx
和msg
(通过GetCorrelationIDs()
)。
我们应该在这里检查唯一性吗?
https://github.com/TheThingsNetwork/lorawan-stack/blob/master/pkg/events/events.go#L148
是的,我们可以将pkg/events/correlation_context.go
的合并算法移到其自己的函数( mergeCorrelationIDs
)中,并在pkg/events/events.go
:
if cids := data.GetCorrelationIDs(); len(cids) > 0 {
cids = append(cids[:0:0], cids...)
sort.Strings(cids)
evt.innerEvent.CorrelationIDs = mergeCorrelationIDs(evt.innerEvent.CorrelationIDs, cids)
}
我们可能应该添加一条注释,必须对evt.innerEvent.CorrelationIDs
进行排序(之所以这样,是因为上下文中的相关ID进行了排序)。
@ pgalic96的状态是什么?
忙于一些事情,我检查了唯一性,就像这样:
if data, ok := data.(interface{ GetCorrelationIDs() []string }); ok {
mapCorrelationIds := make(map[string]struct{})
for _, correlationID := range evt.innerEvent.CorrelationIDs {
mapCorrelationIds[correlationID] = struct{}{}
}
for _, correlationID := range data.GetCorrelationIDs() {
if _, ok := mapCorrelationIds[correlationID]; !ok {
evt.innerEvent.CorrelationIDs = append(evt.innerEvent.CorrelationIDs, correlationID)
}
}
}
尚未编写测试,但是它将使用TestCorrelationID
创建一个事件,然后在有效负载中提供相同的TestCorrelationID
,然后检查消息的CorrelationIDs的长度是否为确实是1,而不是2。
除了变量名外,它通常看起来还不错,尽管evt.innerEvent.CorrelationIDs
不会以这种方式进行重复数据删除
我更喜欢使用@rvolosatovs的合并算法(请参阅我的评论)。 我们已经花了一些时间来为合并相关ID进行有效的实现,因此,如果我们将@ pgalic96的拟议地图实现合并/删除,效率会大大降低,并且还会返回未排序的ID,那将是可耻的。
@ pgalic96您可以提供状态更新吗?
我本周还没有从事这项工作,明天考试后就去上班。 明天将尝试完成。
我将根据@htdvisser的建议更改代码。
最有用的评论
我更喜欢使用@rvolosatovs的合并算法(请参阅我的评论)。 我们已经花了一些时间来为合并相关ID进行有效的实现,因此,如果我们将@ pgalic96的拟议地图实现合并/删除,效率会大大降低,并且还会返回未排序的ID,那将是可耻的。