code.vegaprotocol.io/vega@v0.79.0/core/vegatime/service.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 package vegatime 17 18 import ( 19 "context" 20 "sync" 21 "time" 22 23 "code.vegaprotocol.io/vega/core/events" 24 ) 25 26 //go:generate go run github.com/golang/mock/mockgen -destination mocks/time_service_mock.go -package mocks code.vegaprotocol.io/vega/core/vegatime TimeService 27 type TimeService interface { 28 GetTimeNow() time.Time 29 NotifyOnTick(...func(context.Context, time.Time)) 30 } 31 32 type Broker interface { 33 Send(event events.Event) 34 SendBatch(events []events.Event) 35 } 36 37 // Svc represents the Service managing time inside Vega. 38 // this is basically based on the time of the chain in use. 39 type Svc struct { 40 config Config 41 42 previousTimestamp time.Time 43 currentTimestamp time.Time 44 45 listeners []func(context.Context, time.Time) 46 mu sync.RWMutex 47 48 broker Broker 49 } 50 51 // New instantiates a new vegatime service. 52 func New(conf Config, broker Broker) *Svc { 53 return &Svc{config: conf, broker: broker} 54 } 55 56 // ReloadConf reload the configuration for the vegatime service. 57 func (s *Svc) ReloadConf(conf Config) { 58 // do nothing here, conf is not used for now 59 } 60 61 // SetTimeNow update the current time. 62 func (s *Svc) SetTimeNow(ctx context.Context, t time.Time) { 63 // ensure the t is using UTC 64 t = t.UTC() 65 66 // We need to cache the last timestamp so we can distribute trades 67 // in a block transaction evenly between last timestamp and current timestamp 68 if s.currentTimestamp.Unix() > 0 { 69 s.previousTimestamp = s.currentTimestamp 70 } 71 s.currentTimestamp = t 72 73 // Ensure we always set previousTimestamp it'll be 0 on the first block transaction 74 if s.previousTimestamp.Unix() < 1 { 75 s.previousTimestamp = s.currentTimestamp 76 } 77 78 evt := events.NewTime(ctx, t) 79 s.broker.Send(evt) 80 s.notify(ctx, t) 81 } 82 83 func (s *Svc) SetPrevTime(t time.Time) { 84 s.previousTimestamp = t 85 } 86 87 // GetTimeNow returns the current time in vega. 88 func (s *Svc) GetTimeNow() time.Time { 89 s.mu.RLock() 90 defer s.mu.RUnlock() 91 92 return s.currentTimestamp 93 } 94 95 // NotifyOnTick allows other services to register a callback function 96 // which will be called once the vega time is updated (SetTimeNow is called). 97 func (s *Svc) NotifyOnTick(callbacks ...func(context.Context, time.Time)) { 98 s.mu.Lock() 99 defer s.mu.Unlock() 100 s.listeners = append(s.listeners, callbacks...) 101 } 102 103 // GetTimeLastBatch returns the previous vega time. 104 func (s *Svc) GetTimeLastBatch() time.Time { 105 return s.previousTimestamp 106 } 107 108 func (s *Svc) notify(ctx context.Context, t time.Time) { 109 // Call listeners for triggering actions. 110 for _, f := range s.listeners { 111 f(ctx, t) 112 } 113 }