github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/infura/endblocker.go (about) 1 package infura 2 3 import ( 4 "fmt" 5 "time" 6 7 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 8 ) 9 10 func EndBlocker(ctx sdk.Context, k Keeper) { 11 k.stream.logger.Debug("infura EndBlocker begin") 12 if !k.stream.enable { 13 k.stream.logger.Debug("infura engine is not enable") 14 return 15 } 16 // prepare task data 17 sc := StreamContext{ 18 blockHeight: ctx.BlockHeight(), 19 stream: k.stream, 20 task: newTask(ctx.BlockHeight(), k.stream.cache), 21 } 22 23 // cache queue 24 if k.stream.cacheQueue != nil { 25 k.stream.logger.Debug(fmt.Sprintf("cache queue: len:%d, cap:%d, enqueue:%d", 26 len(k.stream.cacheQueue.queue), cap(k.stream.cacheQueue.queue), sc.blockHeight)) 27 // block if cache queue is full 28 k.stream.cacheQueue.Enqueue(sc) 29 k.metric.CacheSize.Set(float64(len(k.stream.cacheQueue.queue))) 30 return 31 } 32 33 execute(sc) 34 k.stream.logger.Debug("infura EndBlocker end") 35 } 36 37 func prepareStreamTask(blockHeight int64, ctx StreamContext) (taskConst TaskConst, err error) { 38 if ctx.task != nil && ctx.task.Height > blockHeight { 39 return TaskPhase1NextActionJumpNextBlock, nil 40 } 41 42 // fetch distribute lock 43 locked, err := ctx.stream.scheduler.FetchDistLock( 44 distributeLock, ctx.stream.scheduler.GetLockerID(), taskTimeout) 45 46 if !locked || err != nil { 47 return TaskPhase1NextActionRestart, err 48 } 49 50 state := ctx.stream.scheduler.GetDistState(latestTaskKey) 51 if len(state) > 0 { 52 ctx.task, err = parseTaskFromJSON(state) 53 if err != nil { 54 return releaseLockWithStatus(ctx.stream, TaskPhase1NextActionRestart, err) 55 } 56 if ctx.task.Height > blockHeight { 57 return releaseLockWithStatus(ctx.stream, TaskPhase1NextActionJumpNextBlock, nil) 58 } 59 if ctx.task.Height == blockHeight { 60 if ctx.task.GetStatus() == TaskStatusSuccess { 61 return releaseLockWithStatus(ctx.stream, TaskPhase1NextActionJumpNextBlock, nil) 62 } 63 return TaskPhase1NextActionReturnTask, nil 64 } 65 if ctx.task.Height+1 == blockHeight { 66 return TaskPhase1NextActionNewTask, nil 67 } 68 return releaseLockWithStatus(ctx.stream, TaskPhase1NextActionUnknown, 69 fmt.Errorf("error: EndBlock-(%d) should never run into here, distrLatestBlock: %+v", 70 blockHeight, ctx.task)) 71 } 72 return TaskPhase1NextActionNewTask, nil 73 74 } 75 76 func releaseLockWithStatus(s *Stream, taskConst TaskConst, err error) (TaskConst, error) { 77 rSuccess, rErr := s.scheduler.ReleaseDistLock(distributeLock, s.scheduler.GetLockerID()) 78 if !rSuccess || rErr != nil { 79 return TaskPhase1NextActionRestart, rErr 80 } 81 return taskConst, err 82 } 83 84 func executeStreamTask(s *Stream, task *Task) (taskConst TaskConst, err error) { 85 done := s.engine.Write(task.Data) 86 task.Done = done 87 stateStr := task.toJSON() 88 success, err := s.scheduler.UnlockDistLockWithState( 89 distributeLock, s.scheduler.GetLockerID(), latestTaskKey, stateStr) 90 if success && err == nil { 91 if task.GetStatus() != TaskStatusSuccess { 92 return TaskPhase2NextActionRestart, nil 93 } 94 return TaskPhase2NextActionJumpNextBlock, nil 95 } 96 97 return TaskPhase2NextActionRestart, err 98 99 } 100 101 func execute(ctx StreamContext) { 102 for { 103 p1Status, p1err := prepareStreamTask(ctx.blockHeight, ctx) 104 if p1err != nil { 105 ctx.stream.logger.Error(p1err.Error()) 106 } 107 ctx.stream.logger.Debug(fmt.Sprintf("P1Status: %s", TaskConstDesc[p1Status])) 108 switch p1Status { 109 case TaskPhase1NextActionRestart: 110 time.Sleep(1500 * time.Millisecond) 111 continue 112 case TaskPhase1NextActionUnknown: 113 err := fmt.Errorf("infura unexpected exception, %+v", p1err) 114 panic(err) 115 case TaskPhase1NextActionJumpNextBlock: 116 return 117 default: 118 p2Status, p2err := executeStreamTask(ctx.stream, ctx.task) 119 if p2err != nil { 120 ctx.stream.logger.Error(p2err.Error()) 121 } 122 123 ctx.stream.logger.Debug(fmt.Sprintf("P2Status: %s", TaskConstDesc[p2Status])) 124 125 switch p2Status { 126 case TaskPhase2NextActionRestart: 127 time.Sleep(5000 * time.Millisecond) 128 case TaskPhase2NextActionJumpNextBlock: 129 return 130 } 131 } 132 } 133 }