code.vegaprotocol.io/vega@v0.79.0/core/checkpoint/snapshot.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 checkpoint
    17  
    18  import (
    19  	"context"
    20  	"time"
    21  
    22  	"code.vegaprotocol.io/vega/core/types"
    23  	"code.vegaprotocol.io/vega/libs/proto"
    24  	"code.vegaprotocol.io/vega/logging"
    25  )
    26  
    27  func (e *Engine) Namespace() types.SnapshotNamespace {
    28  	return e.state.Namespace()
    29  }
    30  
    31  func (e *Engine) Keys() []string {
    32  	return []string{
    33  		e.state.Key(),
    34  	}
    35  }
    36  
    37  func (e *Engine) Stopped() bool {
    38  	return false
    39  }
    40  
    41  func (e *Engine) setNextCP(t time.Time) {
    42  	e.nextCP = t
    43  	e.state.Checkpoint.NextCp = t.UnixNano()
    44  	e.data = []byte{}
    45  	e.updated = true
    46  }
    47  
    48  func (e *Engine) GetState(k string) ([]byte, []types.StateProvider, error) {
    49  	if k != e.state.Key() {
    50  		return nil, nil, types.ErrSnapshotKeyDoesNotExist
    51  	}
    52  	if len(e.data) == 0 {
    53  		if err := e.serialiseState(); err != nil {
    54  			return nil, nil, err
    55  		}
    56  	}
    57  	return e.data, nil, nil
    58  }
    59  
    60  func (e *Engine) serialiseState() error {
    61  	e.log.Debug("serialising checkpoint", logging.Int64("nextcp", e.state.Checkpoint.NextCp))
    62  	pl := types.Payload{
    63  		Data: e.state,
    64  	}
    65  	data, err := proto.Marshal(pl.IntoProto())
    66  	if err != nil {
    67  		return err
    68  	}
    69  
    70  	e.data = data
    71  	return nil
    72  }
    73  
    74  func (e *Engine) LoadState(_ context.Context, snap *types.Payload) ([]types.StateProvider, error) {
    75  	if snap.Namespace() != e.state.Namespace() {
    76  		return nil, types.ErrInvalidSnapshotNamespace
    77  	}
    78  	if snap.Key() != e.state.Key() {
    79  		return nil, types.ErrSnapshotKeyDoesNotExist
    80  	}
    81  	state := snap.Data.(*types.PayloadCheckpoint)
    82  	e.state = state
    83  	e.setNextCP(time.Unix(0, state.Checkpoint.NextCp))
    84  	e.log.Debug("loaded checkpoint snapshot", logging.Int64("nextcp", e.state.Checkpoint.NextCp))
    85  	return nil, nil
    86  }
    87  
    88  func (e *Engine) PollChanges(ctx context.Context, k string, ch chan<- *types.Payload) {
    89  	e.poll = make(chan struct{})
    90  	defer func() {
    91  		close(e.poll)
    92  	}()
    93  	if k != e.state.Key() {
    94  		e.snapErr = types.ErrSnapshotKeyDoesNotExist
    95  		ch <- nil
    96  		return
    97  	}
    98  	if !e.updated {
    99  		// nil on channel indicates no changes
   100  		ch <- nil
   101  		return
   102  	}
   103  	// create the payload object for snapshot
   104  	pl := types.Payload{
   105  		Data: &types.PayloadCheckpoint{
   106  			Checkpoint: &types.CPState{
   107  				NextCp: e.nextCP.UnixNano(),
   108  			},
   109  		},
   110  	}
   111  	select {
   112  	case <-ctx.Done():
   113  		e.snapErr = ctx.Err()
   114  		return
   115  	default:
   116  		// send new update, flag as done
   117  		ch <- &pl
   118  		e.updated = false
   119  	}
   120  }
   121  
   122  func (e *Engine) Sync() error {
   123  	<-e.poll
   124  	return e.Err()
   125  }
   126  
   127  func (e *Engine) Err() error {
   128  	err := e.snapErr
   129  	// remove error
   130  	e.snapErr = nil
   131  	return err
   132  }