github.com/anycable/anycable-go@v1.5.1/encoders/encoding_cache.go (about)

     1  package encoders
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  
     7  	"github.com/anycable/anycable-go/ws"
     8  )
     9  
    10  type EncodingCache struct {
    11  	// Encoder type to encoded message mapping
    12  	encodedBytes map[string]*ws.SentFrame
    13  }
    14  
    15  type EncodingFunction = func(EncodedMessage) (*ws.SentFrame, error)
    16  
    17  func NewEncodingCache() *EncodingCache {
    18  	return &EncodingCache{make(map[string]*ws.SentFrame)}
    19  }
    20  
    21  func (m *EncodingCache) Fetch(
    22  	msg EncodedMessage,
    23  	encoder string,
    24  	callback EncodingFunction,
    25  ) (*ws.SentFrame, error) {
    26  	if _, ok := m.encodedBytes[encoder]; !ok {
    27  		b, err := callback(msg)
    28  
    29  		if err != nil {
    30  			m.encodedBytes[encoder] = nil
    31  		} else {
    32  			m.encodedBytes[encoder] = b
    33  		}
    34  	}
    35  
    36  	if b := m.encodedBytes[encoder]; b == nil {
    37  		return nil, errors.New("Encoding failed")
    38  	} else {
    39  		return b, nil
    40  	}
    41  }
    42  
    43  type CachedEncodedMessage struct {
    44  	target EncodedMessage
    45  	cache  *EncodingCache
    46  }
    47  
    48  func NewCachedEncodedMessage(msg EncodedMessage) *CachedEncodedMessage {
    49  	return &CachedEncodedMessage{target: msg, cache: NewEncodingCache()}
    50  }
    51  
    52  func (msg *CachedEncodedMessage) GetType() string {
    53  	return msg.target.GetType()
    54  }
    55  
    56  func (msg *CachedEncodedMessage) Fetch(id string, callback EncodingFunction) (*ws.SentFrame, error) {
    57  	return msg.cache.Fetch(msg.target, id, callback)
    58  }
    59  
    60  func (msg *CachedEncodedMessage) MarshalJSON() ([]byte, error) {
    61  	return json.Marshal(msg.target)
    62  }