github.com/annwntech/go-micro/v2@v2.9.5/util/sync/manager.go (about) 1 package sync 2 3 import ( 4 "time" 5 6 "github.com/annwntech/go-micro/v2/store" 7 "github.com/pkg/errors" 8 ) 9 10 type operation struct { 11 operation action 12 record *store.Record 13 deadline time.Time 14 retries int 15 maxiumum int 16 } 17 18 // action represents the type of a queued operation 19 type action int 20 21 const ( 22 readOp action = iota + 1 23 writeOp 24 deleteOp 25 listOp 26 ) 27 28 func (c *syncStore) syncManager() { 29 tickerAggregator := make(chan struct{ index int }) 30 for i, ticker := range c.pendingWriteTickers { 31 go func(index int, c chan struct{ index int }, t *time.Ticker) { 32 for range t.C { 33 c <- struct{ index int }{index: index} 34 } 35 }(i, tickerAggregator, ticker) 36 } 37 for { 38 select { 39 case i := <-tickerAggregator: 40 println(i.index, "ticked") 41 c.processQueue(i.index) 42 } 43 } 44 } 45 46 func (c *syncStore) processQueue(index int) { 47 c.Lock() 48 defer c.Unlock() 49 q := c.pendingWrites[index] 50 for i := 0; i < q.Len(); i++ { 51 r, ok := q.PopFront() 52 if !ok { 53 panic(errors.Errorf("retrieved an invalid value from the L%d sync queue", index+1)) 54 } 55 ir, ok := r.(*internalRecord) 56 if !ok { 57 panic(errors.Errorf("retrieved a non-internal record from the L%d sync queue", index+1)) 58 } 59 if !ir.expiresAt.IsZero() && time.Now().After(ir.expiresAt) { 60 continue 61 } 62 nr := &store.Record{ 63 Key: ir.key, 64 } 65 nr.Value = make([]byte, len(ir.value)) 66 copy(nr.Value, ir.value) 67 if !ir.expiresAt.IsZero() { 68 nr.Expiry = time.Until(ir.expiresAt) 69 } 70 // Todo = internal queue also has to hold the corresponding store.WriteOptions 71 if err := c.syncOpts.Stores[index+1].Write(nr); err != nil { 72 // some error, so queue for retry and bail 73 q.PushBack(ir) 74 return 75 } 76 } 77 } 78 79 func intpow(x, y int64) int64 { 80 result := int64(1) 81 for 0 != y { 82 if 0 != (y & 1) { 83 result *= x 84 } 85 y >>= 1 86 x *= x 87 } 88 return result 89 }