MCPcopy Create free account
hub / github.com/TheThingsNetwork/lorawan-stack / SubscribeWithHistory

Method SubscribeWithHistory

pkg/events/redis/store.go:346–447  ·  view source on GitHub ↗

SubscribeWithHistory is like FetchHistory, but after fetching historical events, this continues sending live events until the context is done.

(
	ctx context.Context, names []string, ids []*ttnpb.EntityIdentifiers, after *time.Time, tail int, hdl events.Handler,
)

Source from the content-addressed store, hash-verified

344// SubscribeWithHistory is like FetchHistory, but after fetching historical events,
345// this continues sending live events until the context is done.
346func (ps *PubSubStore) SubscribeWithHistory(
347 ctx context.Context, names []string, ids []*ttnpb.EntityIdentifiers, after *time.Time, tail int, hdl events.Handler,
348) (err error) {
349 start := "0-0"
350 switch {
351 case after == nil:
352 case after.IsZero():
353 after = nil
354 default:
355 // Truncate to milliseconds to be consistent with the JSON API.
356 afterMS := after.Truncate(time.Millisecond)
357 after = &afterMS
358 // Account for a clock skew on the Redis server of up to 1 second.
359 start = formatStreamTime(after.Add(-1 * time.Second))
360 }
361
362 states := make([]*streamState, len(ids))
363 for i, id := range ids {
364 states[i] = &streamState{
365 id: id,
366 stream: ps.eventStream(ctx, id),
367 start: start,
368 }
369 }
370
371 for _, s := range states {
372 evtPBs, nextStart, err := ps.tailStream(ctx, names, s.id, s.start, tail)
373 if err != nil {
374 return err
375 }
376 for _, evtPB := range evtPBs {
377 if after != nil {
378 if evtTime := ttnpb.StdTime(evtPB.GetTime()); evtTime != nil &&
379 !evtTime.Truncate(time.Millisecond).After(*after) {
380 continue
381 }
382 }
383 evt, err := events.FromProto(evtPB)
384 if err != nil {
385 return err
386 }
387 hdl.Notify(evt)
388 }
389 s.start = nextStart
390 }
391
392 matchNames := xMessageHasEventName(names...)
393
394 // We expect that the subscriber can ingest `tail` events at a time.
395 eventCountLimit := int64(tail)
396 switch {
397 case eventCountLimit < 8:
398 eventCountLimit = 8
399 case eventCountLimit > 1024:
400 eventCountLimit = 1024
401 }
402
403 ch := make(chan []redis.XStream, 1)

Callers

nothing calls this directly

Calls 15

eventStreamMethod · 0.95
tailStreamMethod · 0.95
loadEventDataMethod · 0.95
StdTimeFunction · 0.92
FromProtoFunction · 0.92
NewFunction · 0.92
formatStreamTimeFunction · 0.85
xMessageHasEventNameFunction · 0.85
partitionStreamStatesFunction · 0.85
eventsFromXMessagesFunction · 0.85
AfterMethod · 0.80

Tested by

no test coverage detected