github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/storage/resolver/scheduler.go (about) 1 // Copyright 2022 zGraph Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package resolver 16 17 import ( 18 "context" 19 "sync" 20 "sync/atomic" 21 22 "github.com/cockroachdb/pebble" 23 "github.com/sourcegraph/conc" 24 "github.com/twmb/murmur3" 25 "github.com/vescale/zgraph/storage/kv" 26 ) 27 28 // Scheduler is used to schedule Resolve tasks. 29 type Scheduler struct { 30 running atomic.Bool 31 mu sync.Mutex 32 db *pebble.DB 33 size int 34 resolvers []*resolver 35 wg conc.WaitGroup 36 cancelFn context.CancelFunc 37 } 38 39 func NewScheduler(size int) *Scheduler { 40 s := &Scheduler{ 41 size: size, 42 } 43 return s 44 } 45 46 func (s *Scheduler) SetDB(db *pebble.DB) { 47 s.mu.Lock() 48 defer s.mu.Unlock() 49 s.db = db 50 } 51 52 // Run initializes the resolvers and start to accept resolve tasks. 53 func (s *Scheduler) Run() { 54 if s.running.Swap(true) { 55 return 56 } 57 58 ctx, cancelFn := context.WithCancel(context.Background()) 59 for i := 0; i < s.size; i++ { 60 r := newResolver(s.db) 61 s.resolvers = append(s.resolvers, r) 62 s.wg.Go(func() { r.run(ctx) }) 63 } 64 s.cancelFn = cancelFn 65 } 66 67 // Resolve submits a bundle of keys to resolve 68 func (s *Scheduler) Resolve(keys []kv.Key, startVer, commitVer kv.Version, notifier Notifier) { 69 if len(keys) == 0 { 70 return 71 } 72 for _, key := range keys { 73 idx := int(murmur3.Sum32(key)) % s.size 74 s.resolvers[idx].push(Task{ 75 Key: key, 76 StartVer: startVer, 77 CommitVer: commitVer, 78 Notifier: notifier, 79 }) 80 } 81 } 82 83 func (s *Scheduler) Close() { 84 s.cancelFn() 85 s.wg.Wait() 86 for _, r := range s.resolvers { 87 r.close() 88 } 89 }