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

Function popTask

pkg/redis/redis.go:556–626  ·  view source on GitHub ↗

popTask calls f on the most recent task in the queue, for which timestamp is in range [0, time.Now()] or blocks until such is available or context is done. group is the consumer group name. consumer is the consumer group ID. ReadyTaskKey(k) is the keys to pop from. Pipeline is executed even if f ret

(
	ctx context.Context,
	r redis.Cmdable,
	group, consumer string,
	f func(p redis.Pipeliner, payload string, startAt time.Time) error,
	k string,
	blockLimit time.Duration,
)

Source from the content-addressed store, hash-verified

554// Pipeline is executed even if f returns an error.
555// Tasks are acked only if f returns without error.
556func popTask(
557 ctx context.Context,
558 r redis.Cmdable,
559 group, consumer string,
560 f func(p redis.Pipeliner, payload string, startAt time.Time) error,
561 k string,
562 blockLimit time.Duration,
563) (err error) {
564 readyStream := ReadyTaskKey(k)
565
566 processMessage := func(message redis.XMessage) error {
567 fields := make(map[string]string, len(message.Values))
568 for k, v := range message.Values {
569 val, ok := v.(string)
570 if !ok {
571 panic(fmt.Sprintf("invalid field type %T", v))
572 }
573 fields[k] = val
574 }
575
576 var startAt time.Time
577 if s, ok := fields[startAtKey]; ok {
578 startAt, err = parseTime(s)
579 if err != nil {
580 return errInvalidKeyValueType.WithAttributes("key", startAtKey).WithCause(err)
581 }
582 }
583
584 p := r.Pipeline()
585 defer func() {
586 // Ensure pipeline is executed even if f fails.
587 _, pErr := p.Exec(ctx)
588 if err == nil && pErr != nil {
589 err = ConvertError(pErr)
590 }
591 }()
592
593 if err = f(p, fields[payloadKey], startAt); err != nil {
594 return err
595 }
596
597 p.XAck(ctx, readyStream, group, message.ID)
598 p.XDel(ctx, readyStream, message.ID)
599
600 return nil
601 }
602
603 var xs []redis.XStream
604 for len(xs) == 0 {
605 xs, err = r.XReadGroup(ctx, &redis.XReadGroupArgs{
606 Group: group,
607 Consumer: consumer,
608 Streams: []string{readyStream, ">"},
609 Count: 1,
610 Block: blockLimit,
611 }).Result()
612 if err != nil && !errors.Is(err, redis.Nil) {
613 return ConvertError(err)

Callers 1

PopMethod · 0.85

Calls 7

ReadyTaskKeyFunction · 0.85
ConvertErrorFunction · 0.85
parseTimeFunction · 0.70
ResultMethod · 0.65
WithCauseMethod · 0.45
WithAttributesMethod · 0.45
IsMethod · 0.45

Tested by

no test coverage detected