github.com/kubeshop/testkube@v1.17.23/internal/graphql/services/common.go (about) 1 package services 2 3 import ( 4 "context" 5 6 "github.com/kubeshop/testkube/pkg/api/v1/testkube" 7 "github.com/kubeshop/testkube/pkg/rand" 8 ) 9 10 func Map[T interface{}, U interface{}](list []T, mapper func(item T) U) []U { 11 result := make([]U, len(list)) 12 for i, item := range list { 13 result[i] = mapper(item) 14 } 15 return result 16 } 17 18 func HandleSubscription[T Service, U interface{}]( 19 ctx context.Context, 20 topic string, 21 s T, 22 get func() (U, error), 23 ) (<-chan U, error) { 24 ch := make(chan U, 1) 25 26 // Load initial data 27 initial, err := get() 28 if err == nil { 29 ch <- initial 30 } else { 31 s.Logger().Errorw("failed to get initial data for "+topic, err) 32 return nil, err 33 } 34 35 // Setup queue 36 queue := rand.String(30) 37 err = s.Bus().SubscribeTopic(topic, queue, func(e testkube.Event) error { 38 s.Logger().Debugf("graphql subscription event: %s %s %s", e.Type_, *e.Resource, e.ResourceId) 39 result, err := get() 40 if err != nil { 41 s.Logger().Errorw("failed to get data after change for "+topic, err) 42 return err 43 } 44 ch <- result 45 return nil 46 }) 47 48 if err == nil { 49 s.Logger().Debug("graphql subscription: subscribed to " + topic) 50 go func() { 51 <-ctx.Done() 52 _ = s.Bus().Unsubscribe(queue) 53 close(ch) 54 }() 55 } else { 56 s.Logger().Errorw("graphql subscription: failed to subscribe to "+topic, err) 57 return nil, err 58 } 59 60 return ch, nil 61 }