go-hep.org/x/hep@v0.38.1/fwk/store.go (about) 1 // Copyright ©2017 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package fwk 6 7 import ( 8 "fmt" 9 "reflect" 10 ) 11 12 type achan chan any 13 14 // datastore stores (event) data and provides concurrent-safe access to it. 15 type datastore struct { 16 SvcBase 17 store map[string]achan 18 quit chan struct{} 19 } 20 21 func (ds *datastore) Configure(ctx Context) error { 22 return nil 23 } 24 25 func (ds *datastore) Get(k string) (any, error) { 26 ch, ok := ds.store[k] 27 if !ok { 28 return nil, fmt.Errorf("Store.Get: no such key [%v]", k) 29 } 30 select { 31 case v, ok := <-ch: 32 if !ok { 33 return nil, fmt.Errorf("%s: closed channel for key [%s]", ds.Name(), k) 34 } 35 ch <- v 36 return v, nil 37 case <-ds.quit: 38 return nil, fmt.Errorf("%s: timeout to get [%s]", ds.Name(), k) 39 } 40 } 41 42 func (ds *datastore) Put(k string, v any) error { 43 select { 44 case ds.store[k] <- v: 45 return nil 46 case <-ds.quit: 47 return fmt.Errorf("%s: timeout to put [%s]", ds.Name(), k) 48 } 49 } 50 51 func (ds *datastore) Has(k string) bool { 52 _, ok := ds.store[k] 53 return ok 54 } 55 56 func (ds *datastore) StartSvc(ctx Context) error { 57 ds.store = make(map[string]achan) 58 return nil 59 } 60 61 func (ds *datastore) StopSvc(ctx Context) error { 62 ds.store = make(map[string]achan) 63 return nil 64 } 65 66 // reset deletes the payload and resets the associated channel 67 func (ds *datastore) reset(keys []string) error { 68 var err error 69 for _, k := range keys { 70 ch, ok := ds.store[k] 71 if ok { 72 select { 73 case vv := <-ch: 74 if vv, ok := vv.(Deleter); ok { 75 err = vv.Delete() 76 if err != nil { 77 return err 78 } 79 } 80 default: 81 } 82 } 83 ds.store[k] = make(achan, 1) 84 } 85 ds.quit = make(chan struct{}) 86 return err 87 } 88 89 // close notifies components hanging on store.Get or .Put that event has been aborted 90 func (ds *datastore) close() { 91 close(ds.quit) 92 } 93 94 func init() { 95 Register(reflect.TypeOf(datastore{}), 96 func(typ, name string, mgr App) (Component, error) { 97 return &datastore{ 98 SvcBase: NewSvc(typ, name, mgr), 99 store: make(map[string]achan), 100 quit: make(chan struct{}), 101 }, nil 102 }, 103 ) 104 } 105 106 // interface tests 107 var _ Store = (*datastore)(nil)