main.go (2881B)
1 // Example: Asynchronous state persistence. 2 // 3 // TODO: this example is broken after change to loop 4 package main 5 6 import ( 7 "context" 8 "flag" 9 "fmt" 10 "io/ioutil" 11 "os" 12 "path" 13 14 "git.defalsify.org/vise.git/resource" 15 "git.defalsify.org/vise.git/state" 16 "git.defalsify.org/vise.git/engine" 17 "git.defalsify.org/vise.git/persist" 18 "git.defalsify.org/vise.git/logging" 19 fsdb "git.defalsify.org/vise.git/db/fs" 20 ) 21 22 const ( 23 USERFLAG_ONE = iota + state.FLAG_USERSTART 24 USERFLAG_TWO 25 USERFLAG_THREE 26 USERFLAG_DONE 27 ) 28 29 var ( 30 logg = logging.NewVanilla() 31 ) 32 33 type fsData struct { 34 path string 35 persister *persist.Persister 36 } 37 38 func (fsd *fsData) peek(ctx context.Context, sym string, input []byte) (resource.Result, error) { 39 res := resource.Result{} 40 fp := fsd.path + "_data" 41 f, err := os.Open(fp) 42 if err != nil { 43 return res, err 44 } 45 r, err := ioutil.ReadAll(f) 46 if err != nil { 47 return res, err 48 } 49 res.Content = string(r) 50 return res, nil 51 } 52 53 func (fsd *fsData) poke(ctx context.Context, sym string, input []byte) (resource.Result, error) { 54 res := resource.Result{} 55 fp := fsd.path + "_data" 56 f, err := os.OpenFile(fp, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 57 if err != nil { 58 return res, err 59 } 60 f.Write([]byte("*")) 61 f.Close() 62 63 st := fsd.persister.GetState() 64 for i := 8; i < 12; i++ { 65 v := uint32(i) 66 logg.DebugCtxf(ctx, "checking flag", "flag", v) 67 if st.MatchFlag(v, true) { 68 logg.DebugCtxf(ctx, "match on flag", "flag", v) 69 res.FlagReset = append(res.FlagReset, v) 70 res.FlagSet = append(res.FlagSet, v + 1) 71 break 72 } 73 } 74 if len(res.FlagSet) == 0 { 75 res.FlagSet = append(res.FlagSet, 8) 76 } 77 return res, nil 78 } 79 80 func main() { 81 var dir string 82 var root string 83 var size uint 84 var sessionId string 85 flag.StringVar(&dir, "d", ".", "resource dir to read from") 86 flag.UintVar(&size, "s", 0, "max size of output") 87 flag.StringVar(&root, "root", "root", "entry point symbol") 88 flag.StringVar(&sessionId, "session-id", "default", "session id") 89 flag.Parse() 90 fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir) 91 92 ctx := context.Background() 93 rsStore := fsdb.NewFsDb() 94 err := rsStore.Connect(ctx, dir) 95 if err != nil { 96 panic(err) 97 } 98 rs := resource.NewDbResource(rsStore) 99 cfg := engine.Config{ 100 Root: "root", 101 SessionId: sessionId, 102 FlagCount: 4, 103 } 104 105 dp := path.Join(dir, ".state") 106 store := fsdb.NewFsDb() 107 err = store.Connect(ctx, dp) 108 if err != nil { 109 fmt.Fprintf(os.Stderr, "db connect fail: %s", err) 110 os.Exit(1) 111 } 112 pr := persist.NewPersister(store) 113 114 en := engine.NewEngine(cfg, rs) 115 en = en.WithPersister(pr) 116 117 fp := path.Join(dp, sessionId) 118 aux := &fsData{ 119 path: fp, 120 persister: pr, 121 } 122 rs.AddLocalFunc("poke", aux.poke) 123 rs.AddLocalFunc("peek", aux.peek) 124 125 err = engine.Loop(ctx, en, os.Stdin, os.Stdout, nil) 126 if err != nil { 127 fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err) 128 os.Exit(1) 129 } 130 }