github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/sleep/sleep.go (about) 1 /* 2 * Copyright (C) 2020 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package sleep 19 20 import ( 21 "sync" 22 "time" 23 24 "github.com/rs/zerolog/log" 25 "golang.org/x/net/context" 26 27 "github.com/mysteriumnetwork/node/core/connection/connectionstate" 28 "github.com/mysteriumnetwork/node/eventbus" 29 ) 30 31 // Event represents sleep event triggered by underlying OS 32 type Event int 33 34 const ( 35 // AppTopicSleepNotification represents sleep management Event notification 36 AppTopicSleepNotification = "sleep_notification" 37 38 // EventWakeup event sent to node after OS wakes up from sleep 39 EventWakeup Event = iota 40 // EventSleep event sent to node after OS goes to sleep 41 EventSleep 42 ) 43 44 var eventChannel chan Event 45 46 // Notifier represents sleep event notifier structure 47 type Notifier struct { 48 eventBus eventbus.EventBus 49 stop chan struct{} 50 stopOnce sync.Once 51 connectionManager connectionManager 52 } 53 54 type connectionManager interface { 55 // Status queries current status of connection 56 Status(int) connectionstate.Status 57 // CheckChannel checks if current session channel is alive, returns error on failed keep-alive ping 58 CheckChannel(context.Context) error 59 // Reconnect reconnects current session 60 Reconnect(int) 61 } 62 63 // NewNotifier create sleep events notifier 64 func NewNotifier(manager connectionManager, eventbus eventbus.EventBus) *Notifier { 65 eventChannel = make(chan Event) 66 return &Notifier{ 67 connectionManager: manager, 68 eventBus: eventbus, 69 stop: make(chan struct{}), 70 } 71 } 72 73 func (n *Notifier) handleSleepEvent(e Event) { 74 switch e { 75 case EventSleep: 76 log.Info().Msg("Got sleep notification during live vpn session") 77 case EventWakeup: 78 log.Info().Msg("Got wake-up from sleep notification - checking if need to reconnect") 79 if n.connectionManager.Status(0).State != connectionstate.Connected { 80 return 81 } 82 ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond) 83 defer cancel() 84 if err := n.connectionManager.CheckChannel(ctx); err != nil { 85 log.Info().Msgf("Channel dead - reconnecting: %s", err) 86 n.connectionManager.Reconnect(0) 87 } else { 88 log.Info().Msg("Channel still alive - no need to reconnect") 89 } 90 } 91 } 92 93 // Subscribe subscribes to sleep notifications 94 func (n *Notifier) Subscribe() { 95 n.eventBus.SubscribeAsync(AppTopicSleepNotification, n.handleSleepEvent) 96 }