gitee.com/lh-her-team/common@v1.5.1/shardingbirdsnest/serialize.go (about) 1 // Package shardingbirdsnest serialize 2 package shardingbirdsnest 3 4 import ( 5 "encoding/json" 6 "reflect" 7 "time" 8 9 bn "gitee.com/lh-her-team/common/birdsnest" 10 "gitee.com/lh-her-team/common/shardingbirdsnest/pb" 11 "github.com/gogo/protobuf/proto" 12 ) 13 14 // Start TODO Goroutinue should be turned off using context.Context here 15 func (s *ShardingBirdsNest) Start() { 16 // start serialize monitor 17 go s.serializeMonitor() 18 // start serialize timed 19 go s.serializeTimed() 20 // start all bird's nest 21 for i := range s.bn { 22 s.bn[i].Start() 23 } 24 } 25 26 // Serialize serialize to wal 27 func (s *ShardingBirdsNest) Serialize() error { 28 t := time.Now() 29 // Logs are print after the method is complete 30 defer func(log bn.Logger) { 31 elapsed := time.Since(t) 32 log.Infof("sharding bird's nest serialize success elapsed: %v", elapsed) 33 }(s.log) 34 // config to json 35 conf, err := json.Marshal(s.config) 36 if err != nil { 37 return err 38 } 39 // sharding bird's nest pb 40 sbn := &pb.ShardingBirdsNest{ 41 Length: s.config.Length, 42 Height: s.height, 43 Config: conf, 44 } 45 // sharding bird's nest pb to byte 46 data, err := proto.Marshal(sbn) 47 if err != nil { 48 return err 49 } 50 // snapshot data 51 err = s.snapshot.Write(data) 52 if err != nil { 53 return err 54 } 55 // cover pre height 56 s.preHeight.Store(s.height) 57 return nil 58 } 59 60 // Deserialize deserialize configuration 61 func (s *ShardingBirdsNest) Deserialize() error { 62 // read snapshot 63 data, err := s.snapshot.Read() 64 if err != nil { 65 return err 66 } 67 // If there is no data on the disk, the procedure ends 68 if data == nil { 69 return nil 70 } 71 sharding := new(pb.ShardingBirdsNest) 72 // unmarshal data to pb sharding bird's nest 73 err = proto.Unmarshal(data, sharding) 74 if err != nil { 75 return err 76 } 77 var sbnConfig ShardingBirdsNestConfig 78 err = json.Unmarshal(sharding.Config, &sbnConfig) 79 if err != nil { 80 return err 81 } 82 // equal disk config and file config 83 if reflect.DeepEqual(sbnConfig, s.config) { 84 err = ErrCannotModifyTheNestConfiguration 85 } 86 s.height = sharding.Height 87 return err 88 } 89 90 // serializeMonitor start serialize monitor TODO Goroutinue should be turned off using context.Context here 91 func (s *ShardingBirdsNest) serializeMonitor() { 92 for { // nolint 93 select { 94 // 只有当前"序列化类型"的信号才能过来 95 case signal := <-s.serializeC: 96 t, ok := bn.SerializeIntervalType_name[signal.typ] 97 if !ok { 98 s.log.Errorf("serialize type %v not support", t) 99 } 100 switch signal.typ { 101 case bn.SerializeIntervalType_Height: 102 // 并且 当前高度 - 上次持久化高度 < 高度间隔 则不做持久化 否则,执行持久化 103 // eg: 85 - 80 = 5 < 10 104 // 5 < 10 true 则不做持久化 105 if s.height-s.preHeight.Load() < s.config.Snapshot.BlockHeight.Interval { 106 continue 107 } 108 case bn.SerializeIntervalType_Timed, bn.SerializeIntervalType_Exit: 109 // "时间序列化类型"和"退出序列化类型"直接处理 110 default: 111 continue 112 } 113 // serialize 114 err := s.Serialize() 115 if err != nil { 116 s.log.Errorf("serialize error type: %v, error: %v", t, err) 117 } 118 } 119 } 120 } 121 122 // serializeTimed serialize by timed sign 123 func (s *ShardingBirdsNest) serializeTimed() { 124 // The current serialization type terminates if it is not bn.SerializeIntervalType_Timed 125 if s.config.Snapshot.Type != bn.SerializeIntervalType_Timed { 126 return 127 } 128 // start Timing task 129 ticker := time.NewTicker(time.Second * time.Duration(s.config.Snapshot.Timed.Interval)) 130 // nolint 131 for { 132 select { 133 case <-ticker.C: 134 // Timing signal 135 s.serializeC <- serializeSignal{typ: bn.SerializeIntervalType_Timed} 136 } 137 } 138 } 139 140 // serializeExit serialize by exit sign 141 // nolint: unused 142 func (s *ShardingBirdsNest) serializeExit() { 143 // send bn.SerializeIntervalType_Exit sign 144 s.serializeC <- serializeSignal{typ: bn.SerializeIntervalType_Exit} 145 } 146 147 // serializeHeight serialize by SerializeIntervalType_Height sign 148 func (s *ShardingBirdsNest) serializeHeight(height uint64) { 149 if s.config.Snapshot.Type != bn.SerializeIntervalType_Height { 150 return 151 } 152 // send bn.SerializeIntervalType_Height sign 153 s.serializeC <- serializeSignal{typ: bn.SerializeIntervalType_Height, height: height} 154 } 155 156 // Serialize signal 157 type serializeSignal struct { 158 // typ bn.SerializeIntervalType type 159 typ bn.SerializeIntervalType 160 // current height 161 height uint64 162 }