code.vegaprotocol.io/vega@v0.79.0/core/datasource/common/time.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 //lint:file-ignore ST1003 Ignore underscores in names, this is straigh copied from the proto package to ease introducing the domain types 17 18 package common 19 20 import ( 21 "errors" 22 "fmt" 23 "strings" 24 "time" 25 26 "code.vegaprotocol.io/vega/libs/ptr" 27 datapb "code.vegaprotocol.io/vega/protos/vega/data/v1" 28 ) 29 30 type InternalTimeTrigger struct { 31 // This is optional to reflect the proto, but it will always be set by the governance 32 Initial *time.Time 33 Every int64 34 nextTrigger *time.Time 35 } 36 37 func (i InternalTimeTrigger) String() string { 38 return fmt.Sprintf( 39 "initial(%v) every(%d) nextTrigger(%v)", 40 i.Initial, 41 i.Every, 42 i.nextTrigger, 43 ) 44 } 45 46 func (i InternalTimeTrigger) IntoProto() *datapb.InternalTimeTrigger { 47 var initial *int64 48 if i.Initial != nil { 49 initial = ptr.From(i.Initial.Unix()) 50 } 51 52 return &datapb.InternalTimeTrigger{ 53 Initial: initial, 54 Every: i.Every, 55 } 56 } 57 58 func (i InternalTimeTrigger) DeepClone() *InternalTimeTrigger { 59 var initial *time.Time 60 if i.Initial != nil { 61 initial = *ptr.From(i.Initial) 62 } 63 64 var nextTrigger *time.Time 65 if i.nextTrigger != nil { 66 nextTrigger = *ptr.From(i.nextTrigger) 67 } 68 69 return &InternalTimeTrigger{ 70 Initial: initial, 71 Every: i.Every, 72 nextTrigger: nextTrigger, 73 } 74 } 75 76 func (i InternalTimeTrigger) IsTriggered(timeNow time.Time) bool { 77 if i.nextTrigger == nil { 78 return false 79 } 80 81 triggered := false 82 for i.nextTrigger.Before(timeNow) { 83 triggered = true 84 *i.nextTrigger = i.nextTrigger.Add(time.Duration(i.Every) * time.Second) 85 } 86 87 return triggered 88 } 89 90 func (i *InternalTimeTrigger) SetNextTrigger(timeNow time.Time) { 91 if i.Initial == nil { 92 // Set panic 93 panic("initial time value is missing") 94 } 95 96 i.nextTrigger = ptr.From(*i.Initial) 97 98 // If initial > timeNow, we never been triggered 99 // so we set the next trigger to `initial` 100 if i.Initial.After(timeNow) { 101 return 102 } 103 104 // If `initial` is in the past, we have been triggered already 105 // then -> find when the next trigger is 106 for i.nextTrigger.Before(timeNow) { 107 *i.nextTrigger = i.nextTrigger.Add(time.Duration(i.Every) * time.Second) 108 } 109 } 110 111 func (i *InternalTimeTrigger) SetInitial(initial, timeNow time.Time) { 112 if i.Initial != nil { 113 // this is incorrect, we should only overwrite time 114 // when not submitted by the user 115 panic("invalid initial time override") 116 } 117 118 i.Initial = ptr.From(initial) 119 } 120 121 func InternalTimeTriggerFromProto( 122 protoTrigger *datapb.InternalTimeTrigger, 123 ) *InternalTimeTrigger { 124 var initial *time.Time 125 if protoTrigger.Initial != nil { 126 initial = ptr.From(time.Unix(*protoTrigger.Initial, 0)) 127 } 128 129 tt := &InternalTimeTrigger{ 130 Initial: initial, 131 Every: protoTrigger.Every, 132 } 133 return tt 134 } 135 136 type InternalTimeTriggers [1]*InternalTimeTrigger 137 138 func (i InternalTimeTriggers) Empty() error { 139 if len(i) <= 0 || i[0] == nil { 140 return errors.New("no time trigger is set") 141 } 142 143 return nil 144 } 145 146 func (i InternalTimeTriggers) String() string { 147 if len(i) != 1 { 148 return "[]" 149 } 150 151 strs := make([]string, 0, len(i)) 152 for _, f := range i { 153 // We handle length of 1 for the moment, but later will be extended. 154 if f == nil { 155 strs = append(strs, "nil") 156 continue 157 } 158 strs = append(strs, f.String()) 159 } 160 return "[" + strings.Join(strs, ", ") + "]" 161 } 162 163 func (i InternalTimeTriggers) IntoProto() []*datapb.InternalTimeTrigger { 164 protoTriggers := [1]*datapb.InternalTimeTrigger{} 165 if len(i) == 1 { 166 if len(i) == 1 && i[0] != nil { 167 protoTriggers[0] = i[0].IntoProto() 168 } 169 } 170 171 return protoTriggers[:] 172 } 173 174 func InternalTimeTriggersFromProto(protoTriggers []*datapb.InternalTimeTrigger) InternalTimeTriggers { 175 ts := InternalTimeTriggers{} 176 for i, protoTrigger := range protoTriggers { 177 // Handle length of 1 for now 178 if i == 0 { 179 ts[0] = InternalTimeTriggerFromProto(protoTrigger) 180 } 181 } 182 183 return ts 184 } 185 186 func (i InternalTimeTriggers) DeepClone() InternalTimeTriggers { 187 clonedTriggers := InternalTimeTriggers{} 188 if len(i) == 1 && i[0] != nil { 189 clonedTriggers[0] = i[0].DeepClone() 190 } 191 192 return clonedTriggers 193 } 194 195 func (i InternalTimeTriggers) IsTriggered(now time.Time) bool { 196 for _, v := range i { 197 if v.IsTriggered(now) { 198 return true 199 } 200 } 201 202 return false 203 }