github.com/0chain/gosdk@v1.17.11/wasmsdk/cache.go (about) 1 //go:build js && wasm 2 // +build js,wasm 3 4 package main 5 6 import ( 7 "context" 8 "errors" 9 "time" 10 11 "github.com/0chain/gosdk/wasmsdk/jsbridge" 12 "github.com/0chain/gosdk/zboxcore/client" 13 "github.com/0chain/gosdk/zboxcore/sdk" 14 lru "github.com/hashicorp/golang-lru/v2" 15 ) 16 17 type cachedAllocation struct { 18 Expiration time.Time 19 Allocation *sdk.Allocation 20 } 21 22 var ( 23 cachedAllocations, _ = lru.New[string, *cachedAllocation](100) 24 ) 25 26 // getAllocation get allocation from cache 27 // if not found in cache, fetch from blockchain 28 // and store in cache 29 // - allocationId is the allocation id 30 func getAllocation(allocationId string) (*sdk.Allocation, error) { 31 32 it, ok := cachedAllocations.Get(allocationId) 33 34 if ok { 35 if ok && it.Expiration.After(time.Now()) { 36 return it.Allocation, nil 37 } 38 } 39 sdk.SetWasm() 40 a, err := sdk.GetAllocation(allocationId) 41 if err != nil { 42 return nil, err 43 } 44 sdk.SetShouldVerifyHash(false) 45 it = &cachedAllocation{ 46 Allocation: a, 47 Expiration: time.Now().Add(120 * time.Minute), 48 } 49 50 cachedAllocations.Add(allocationId, it) 51 return it.Allocation, nil 52 } 53 54 // clearAllocation remove allocation from caching 55 func clearAllocation(allocationID string) { 56 cachedAllocations.Remove(allocationID) 57 } 58 59 // reloadAllocation reload allocation from blockchain and update cache 60 // - allocationID is the allocation id 61 func reloadAllocation(allocationID string) (*sdk.Allocation, error) { 62 a, err := sdk.GetAllocation(allocationID) 63 if err != nil { 64 return nil, err 65 } 66 67 it := &cachedAllocation{ 68 Allocation: a, 69 Expiration: time.Now().Add(5 * time.Minute), 70 } 71 72 cachedAllocations.Add(allocationID, it) 73 74 return it.Allocation, nil 75 } 76 77 func addWebWorkers(alloc *sdk.Allocation) (err error) { 78 c := client.GetClient() 79 if c == nil || len(c.Keys) == 0 { 80 return 81 } 82 ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) 83 defer cancel() 84 respChan := make(chan error, len(alloc.Blobbers)) 85 respRequired := 0 86 for _, blober := range alloc.Blobbers { 87 weborker, workerCreated, _ := jsbridge.NewWasmWebWorker(blober.ID, 88 blober.Baseurl, 89 c.ClientID, 90 c.ClientKey, 91 c.PeerPublicKey, 92 c.Keys[0].PublicKey, 93 c.Keys[0].PrivateKey, 94 c.Mnemonic, 95 c.IsSplit) //nolint:errcheck 96 if workerCreated { 97 respRequired++ 98 go func() { 99 eventChan, err := weborker.Listen(ctx) 100 if err != nil { 101 respChan <- err 102 return 103 } 104 _, ok := <-eventChan 105 if !ok { 106 respChan <- errors.New("worker chan closed") 107 return 108 } 109 respChan <- nil 110 }() 111 } 112 } 113 if respRequired == 0 { 114 return 115 } 116 for { 117 select { 118 case <-ctx.Done(): 119 PrintError(ctx.Err()) 120 return ctx.Err() 121 case err = <-respChan: 122 if err != nil { 123 PrintError(err) 124 return 125 } 126 respRequired-- 127 if respRequired == 0 { 128 close(respChan) 129 return 130 } 131 } 132 } 133 }