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  }