github.com/prysmaticlabs/prysm@v1.4.4/shared/logutil/stream.go (about)

     1  package logutil
     2  
     3  import (
     4  	"io"
     5  
     6  	lru "github.com/hashicorp/golang-lru"
     7  	"github.com/prysmaticlabs/prysm/shared/event"
     8  	"github.com/prysmaticlabs/prysm/shared/rand"
     9  )
    10  
    11  const (
    12  	// The number of log entries to keep in memory.
    13  	logCacheSize = 20
    14  )
    15  
    16  var (
    17  	// Compile time interface checks.
    18  	_ = io.Writer(&StreamServer{})
    19  	_ = Streamer(&StreamServer{})
    20  )
    21  
    22  // Streamer defines a struct which can retrieve and stream process logs.
    23  type Streamer interface {
    24  	GetLastFewLogs() [][]byte
    25  	LogsFeed() *event.Feed
    26  }
    27  
    28  // StreamServer defines a a websocket server which can receive events from
    29  // a feed and write them to open websocket connections.
    30  type StreamServer struct {
    31  	feed  *event.Feed
    32  	cache *lru.Cache
    33  }
    34  
    35  // NewStreamServer initializes a new stream server capable of
    36  // streaming log events.
    37  func NewStreamServer() *StreamServer {
    38  	c, err := lru.New(logCacheSize)
    39  	if err != nil {
    40  		panic(err) // This can only occur when the LogCacheSize is negative.
    41  	}
    42  	ss := &StreamServer{
    43  		feed:  new(event.Feed),
    44  		cache: c,
    45  	}
    46  	addLogWriter(ss)
    47  	return ss
    48  }
    49  
    50  // GetLastFewLogs returns the last few entries of logs stored in an LRU cache.
    51  func (ss *StreamServer) GetLastFewLogs() [][]byte {
    52  	messages := make([][]byte, 0)
    53  	for _, k := range ss.cache.Keys() {
    54  		d, ok := ss.cache.Get(k)
    55  		if ok {
    56  			messages = append(messages, d.([]byte))
    57  		}
    58  	}
    59  	return messages
    60  }
    61  
    62  // LogsFeed returns a feed callers can subscribe to to receive logs via a channel.
    63  func (ss *StreamServer) LogsFeed() *event.Feed {
    64  	return ss.feed
    65  }
    66  
    67  // Write a binary message and send over the event feed.
    68  func (ss *StreamServer) Write(p []byte) (n int, err error) {
    69  	ss.feed.Send(p)
    70  	ss.cache.Add(rand.NewGenerator().Uint64(), p)
    71  	return len(p), nil
    72  }