code.vegaprotocol.io/vega@v0.79.0/datanode/broker/deserialize.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package broker
    17  
    18  import (
    19  	"context"
    20  	"fmt"
    21  
    22  	"code.vegaprotocol.io/vega/core/events"
    23  	"code.vegaprotocol.io/vega/libs/proto"
    24  	eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1"
    25  )
    26  
    27  type Deserializer struct {
    28  	source RawEventReceiver
    29  }
    30  
    31  func NewDeserializer(source RawEventReceiver) *Deserializer {
    32  	return &Deserializer{
    33  		source: source,
    34  	}
    35  }
    36  
    37  func (e *Deserializer) Listen() error {
    38  	return e.source.Listen()
    39  }
    40  
    41  func (e *Deserializer) Receive(ctx context.Context) (<-chan events.Event, <-chan error) {
    42  	in, inErr := e.source.Receive(ctx)
    43  
    44  	out := make(chan events.Event)
    45  	outErr := make(chan error)
    46  
    47  	go func() {
    48  		defer close(out)
    49  		defer close(outErr)
    50  
    51  		for {
    52  			select {
    53  			case rawEvent, ok := <-in:
    54  				if !ok {
    55  					return
    56  				}
    57  				event, err := deserializeEvent(rawEvent)
    58  				if err != nil {
    59  					outErr <- err
    60  					return
    61  				}
    62  
    63  				// Listen for context cancels, even if we're blocked sending events
    64  				select {
    65  				case out <- event:
    66  				case <-ctx.Done():
    67  					return
    68  				}
    69  			case err, ok := <-inErr:
    70  				if !ok {
    71  					return
    72  				}
    73  				// Listen for context cancels, even if we're blocked sending events
    74  				select {
    75  				case outErr <- err:
    76  				case <-ctx.Done():
    77  					return
    78  				}
    79  			}
    80  		}
    81  	}()
    82  	return out, outErr
    83  }
    84  
    85  func deserializeEvent(rawEvent []byte) (events.Event, error) {
    86  	busEvent := &eventspb.BusEvent{}
    87  
    88  	if err := proto.Unmarshal(rawEvent, busEvent); err != nil {
    89  		return nil, fmt.Errorf("failed to unmarshal bus event: %w", err)
    90  	}
    91  
    92  	if busEvent.Version != eventspb.Version {
    93  		return nil, fmt.Errorf("mismatched BusEvent version received: %d, want %d", busEvent.Version, eventspb.Version)
    94  	}
    95  
    96  	event := toEvent(context.Background(), busEvent)
    97  	if event == nil {
    98  		return nil, fmt.Errorf("cannot convert proto %q event to internal event", busEvent.GetType().String())
    99  	}
   100  	return event, nil
   101  }