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  }