github.com/vmware/transport-go@v1.3.4/bus/mutation_store_stream.go (about) 1 // Copyright 2019-2020 VMware, Inc. 2 // SPDX-License-Identifier: BSD-2-Clause 3 4 package bus 5 6 import ( 7 "fmt" 8 "sync" 9 ) 10 11 type MutationRequest struct { 12 Request interface{} 13 RequestType interface{} 14 SuccessHandler func(interface{}) 15 ErrorHandler func(interface{}) 16 } 17 18 type MutationRequestHandlerFunction func(mutationReq *MutationRequest) 19 20 // Interface for subscribing for mutation requests 21 type MutationStoreStream interface { 22 // Subscribe to the mutation requests stream. 23 Subscribe(handler MutationRequestHandlerFunction) error 24 // Unsubscribe from the stream. 25 Unsubscribe() error 26 } 27 28 type mutationStreamFilter struct { 29 requestTypes []interface{} 30 } 31 32 func (f *mutationStreamFilter) match(mutationReq *MutationRequest) bool { 33 if len(f.requestTypes) == 0 { 34 return true 35 } 36 37 for _, s := range f.requestTypes { 38 if mutationReq.RequestType == s { 39 return true 40 } 41 } 42 43 return false 44 } 45 46 type mutationStoreStream struct { 47 handler MutationRequestHandlerFunction 48 lock sync.RWMutex 49 store *busStore 50 filter *mutationStreamFilter 51 } 52 53 func newMutationStoreStream(store *busStore, filter *mutationStreamFilter) *mutationStoreStream { 54 stream := new(mutationStoreStream) 55 stream.store = store 56 stream.filter = filter 57 return stream 58 } 59 60 func (ms *mutationStoreStream) Subscribe(handler MutationRequestHandlerFunction) error { 61 if handler == nil { 62 return fmt.Errorf("invalid MutationRequestHandlerFunction") 63 } 64 65 ms.lock.Lock() 66 if ms.handler != nil { 67 ms.lock.Unlock() 68 return fmt.Errorf("stream already subscribed") 69 } 70 ms.handler = handler 71 ms.lock.Unlock() 72 73 ms.store.onMutationStreamSubscribe(ms) 74 return nil 75 } 76 77 func (ms *mutationStoreStream) Unsubscribe() error { 78 ms.lock.Lock() 79 if ms.handler == nil { 80 ms.lock.Unlock() 81 return fmt.Errorf("stream not subscribed") 82 } 83 ms.handler = nil 84 ms.lock.Unlock() 85 86 ms.store.onMutationStreamUnsubscribe(ms) 87 return nil 88 } 89 90 func (ms *mutationStoreStream) onMutationRequest(mutationReq *MutationRequest) { 91 if !ms.filter.match(mutationReq) { 92 return 93 } 94 95 ms.lock.RLock() 96 defer ms.lock.RUnlock() 97 if ms.handler != nil { 98 go ms.handler(mutationReq) 99 } 100 }