snapshot

package
v0.0.0-...-917641f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 30, 2019 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package snapshot manages session storage

Snapshots are session meta data (version, pending), the actual app value and the transformed/merged ops cache.

The Bolt{} type writes the snapshot to a bolt-db (taking care to to incremental writes).

Example (ClientServerUsingBoltDB)
package main

import (
	"fmt"
	"log"
	"net/http/httptest"
	"os"
	"os/signal"
	"reflect"
	"runtime"
	"syscall"

	"github.com/dotchain/dot"
	"github.com/dotchain/dot/changes"
	"github.com/dotchain/dot/changes/types"
	"github.com/dotchain/dot/ops"

	"github.com/dotchain/dot/x/snapshot"
)

func dumpCallStack() func() {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		if sig := <-c; sig != nil {
			stacktrace := make([]byte, 8192)
			length := runtime.Stack(stacktrace, true)
			log.Println(string(stacktrace[:length]))
			os.Exit(1)
		}
	}()
	return func() {
		signal.Stop(c)
		close(c)
	}
}

func main() {
	defer dumpCallStack()()
	defer remove("file.bolt")()
	defer remove("snap.bolt")()

	// start server
	url, close := startServer("file.bolt")
	defer close()

	bolt := snapshot.Bolt{Path: "snap.bolt"}

	// open stream
	session, _, err := bolt.Load()
	if err != nil {
		fmt.Println("Error", err)
	}
	s, store := session.Stream(url, nil)

	// make a couple of changes
	c1 := changes.Replace{Before: changes.Nil, After: types.S8("hello")}
	c2 := changes.Replace{Before: types.S8("hello"), After: types.S8("hello2")}
	s = s.Append(c1).Append(c2)

	// flsuh
	if err := s.Push(); err != nil {
		fmt.Println("Error", err)
	}
	if err := s.Pull(); err != nil {
		fmt.Println("Error", err)
	}

	store.Close()
	// write out session and confirm it matches
	if err := bolt.Save(session, c2.After); err != nil {
		fmt.Println("Error", err)
	}

	sess, v2, err := bolt.Load()
	if err != nil {
		fmt.Println("Error", err)
	}

	// Validate
	if sess.Version != 0 || v2 != c2.After {
		fmt.Println("Mismatch", sess.Version, v2, c2.After)
	}

	if !reflect.DeepEqual(session.OpCache, sess.OpCache) {
		fmt.Println("Mismatch", session.OpCache, sess.OpCache)
	}

	if !reflect.DeepEqual(session.MergeCache, sess.MergeCache) {
		fmt.Println("Mismatch", session.MergeCache, sess.MergeCache)
	}

	if !nilCheck(session.Pending, sess.Pending) {
		fmt.Println("Mismatch", session.Pending, sess.Pending)
	}

	if !nilCheck(session.Merge, sess.Merge) {
		fmt.Println("Mismatch", session.Merge, sess.Merge)
	}

}

func remove(fname string) func() {
	if err := os.Remove(fname); err != nil {
		log.Println("Couldnt remove file", fname)
	}
	return func() {
		if err := os.Remove(fname); err != nil {
			log.Println("Couldnt remove file", fname)
		}
	}
}

func startServer(fname string) (url string, close func()) {
	logger := log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile)
	srv := dot.WithLogger(dot.BoltServer("file.bolt"), logger)
	httpSrv := httptest.NewServer(srv)

	return httpSrv.URL, func() {
		dot.CloseServer(srv)
		httpSrv.Close()
	}
}

func nilCheck(l, r []ops.Op) bool {
	if len(l) == 0 && len(r) == 0 {
		return true
	}
	return reflect.DeepEqual(l, r)
}
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Bolt

type Bolt struct {
	Path    string
	Initial changes.Value
	nw.Codec
}

Bolt represents a local file (bolt db) storage

Path is the path to the file to write snapshots

Initial is the initial app state. This can be nil if the app starts from scratch (in which case it is mapped to changes.Nil)

Codec is the codec to use. If not specified, the default codec is used

func (*Bolt) Load

func (f *Bolt) Load() (*dot.Session, changes.Value, error)

Load loads the snapshot value

func (*Bolt) Save

func (f *Bolt) Save(s *dot.Session, latest changes.Value) error

Save updates the snapshot with changes

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL