github.com/suiyunonghen/DxCommonLib@v0.5.3/sync/sharecalls.go (about) 1 /** 2 并发共享函数调用返回的库 3 */ 4 package sync 5 6 import ( 7 "sync" 8 ) 9 10 type funcCall struct { 11 shareID int 12 shareKey string 13 callErr error 14 result interface{} 15 sync.WaitGroup 16 } 17 18 type ShareCalls struct { 19 fCalls []*funcCall 20 keyCalls []*funcCall 21 sync.RWMutex 22 } 23 24 func (calls *ShareCalls)ShareCall(shareID int,fn func(...interface{})(interface{},error),params ...interface{})(result interface{},fromShareCache bool,err error){ 25 calls.Lock() 26 for i := 0;i<len(calls.fCalls);i++{ 27 if calls.fCalls[i].shareID == shareID{ 28 c := calls.fCalls[i] 29 calls.Unlock() 30 c.Wait() 31 return c.result, true,c.callErr 32 } 33 } 34 if cap(calls.fCalls) == 0{ 35 calls.fCalls = make([]*funcCall,0,16) 36 } 37 call := &funcCall{ 38 shareID: shareID, 39 } 40 call.Add(1) 41 calls.fCalls = append(calls.fCalls,call) 42 calls.Unlock() 43 44 //执行函数 45 call.result,call.callErr = fn(params...) 46 47 //执行完毕 48 calls.Lock() 49 for i := 0;i<len(calls.fCalls);i++{ 50 if calls.fCalls[i].shareID == shareID{ 51 calls.fCalls[i] = nil 52 calls.fCalls = append(calls.fCalls[:i],calls.fCalls[i+1:]...) 53 break 54 } 55 } 56 calls.Unlock() 57 58 call.Done() 59 return call.result,false,call.callErr 60 } 61 62 func (calls *ShareCalls)ShareCallByKey(sharekey string,fn func(...interface{})(interface{},error),params ...interface{})(result interface{},fromShareCache bool,err error){ 63 calls.Lock() 64 for i := 0;i<len(calls.keyCalls);i++{ 65 if calls.keyCalls[i].shareKey == sharekey{ 66 c := calls.keyCalls[i] 67 calls.Unlock() 68 c.Wait() 69 return c.result, true,c.callErr 70 } 71 } 72 if cap(calls.keyCalls) == 0{ 73 calls.keyCalls = make([]*funcCall,0,16) 74 } 75 call := &funcCall{ 76 shareKey: sharekey, 77 } 78 call.Add(1) 79 calls.keyCalls = append(calls.keyCalls,call) 80 calls.Unlock() 81 //执行函数 82 call.result,call.callErr = fn(params...) 83 84 //执行完毕 85 calls.Lock() 86 for i := 0;i<len(calls.keyCalls);i++{ 87 if calls.keyCalls[i].shareKey == sharekey{ 88 calls.keyCalls[i] = nil 89 calls.keyCalls = append(calls.keyCalls[:i],calls.keyCalls[i+1:]...) 90 break 91 } 92 } 93 calls.Unlock() 94 95 call.Done() 96 return call.result,false,call.callErr 97 }