Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve HeartBeat events #653

Merged
merged 1 commit into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion cmd/daemon/events_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
package main

import (
"time"

"github.com/NordSecurity/nordvpn-linux/config"
"github.com/NordSecurity/nordvpn-linux/core"
"github.com/NordSecurity/nordvpn-linux/events"
Expand Down Expand Up @@ -34,7 +36,7 @@ func (*dummyAnalytics) NotifyMFA(bool) error { return n
func (*dummyAnalytics) NotifyAccountCheck(any) error { return nil }
func (*dummyAnalytics) NotifyRequestAPI(events.DataRequestAPI) error { return nil }
func (*dummyAnalytics) NotifyUiItemsClick(events.UiItemsAction) error { return nil }
func (*dummyAnalytics) NotifyHeartBeat(int) error { return nil }
func (*dummyAnalytics) NotifyHeartBeat(time.Duration) error { return nil }
func (*dummyAnalytics) NotifyDeviceLocation(core.Insights) error { return nil }
func (*dummyAnalytics) NotifyLANDiscovery(bool) error { return nil }
func (*dummyAnalytics) NotifyVirtualLocation(bool) error { return nil }
Expand Down
8 changes: 7 additions & 1 deletion cmd/daemon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"path/filepath"
"runtime"
"strconv"
"time"

"golang.org/x/net/netutil"

Expand Down Expand Up @@ -149,6 +150,7 @@ func main() {
debugSubject := &subs.Subject[string]{}
infoSubject := &subs.Subject[string]{}
errSubject := &subs.Subject[error]{}
heartBeatSubject := &subs.Subject[time.Duration]{}
httpCallsSubject := &subs.Subject[events.DataRequestAPI]{}

loggerSubscriber := logger.Subscriber{}
Expand Down Expand Up @@ -290,6 +292,10 @@ func main() {
daemonEvents.Service.Connect.Subscribe(loggerSubscriber.NotifyConnect)
daemonEvents.Settings.Publish(cfg)

// Subscribing after initial settings publishing ensures that heartbeat is not sent with
// the first `NotifyMeshnet` call but will be sent on the first heartbeat job.
heartBeatSubject.Subscribe(analytics.NotifyHeartBeat)

if fsystem.NewInstallation {
daemonEvents.Service.UiItemsClick.Publish(events.UiItemsAction{ItemName: "first_open", ItemType: "button", ItemValue: "first_open", FormReference: "daemon"})
}
Expand Down Expand Up @@ -556,7 +562,7 @@ func main() {
log.Println(internal.WarningPrefix, err)
}
}()
rpc.StartJobs(statePublisher)
rpc.StartJobs(statePublisher, heartBeatSubject)
meshService.StartJobs()
rpc.StartKillSwitch()
if internal.IsSystemd() {
Expand Down
4 changes: 0 additions & 4 deletions daemon/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ func NewEvents(
Disconnect: disconnect,
AccountCheck: accountCheck,
UiItemsClick: uiItemsClick,
HeartBeat: heartBeat,
DeviceLocation: deviceLocation,
},
User: &LoginEvents{
Expand Down Expand Up @@ -187,7 +186,6 @@ type ServicePublisher interface {
NotifyDisconnect(events.DataDisconnect) error
NotifyAccountCheck(any) error
NotifyUiItemsClick(events.UiItemsAction) error
NotifyHeartBeat(int) error
NotifyDeviceLocation(core.Insights) error
}

Expand All @@ -196,7 +194,6 @@ type ServiceEvents struct {
Disconnect events.PublishSubcriber[events.DataDisconnect]
AccountCheck events.PublishSubcriber[any]
UiItemsClick events.PublishSubcriber[events.UiItemsAction]
HeartBeat events.PublishSubcriber[int]
DeviceLocation events.PublishSubcriber[core.Insights]
}

Expand All @@ -205,7 +202,6 @@ func (s *ServiceEvents) Subscribe(to ServicePublisher) {
s.Disconnect.Subscribe(to.NotifyDisconnect)
s.AccountCheck.Subscribe(to.NotifyAccountCheck)
s.UiItemsClick.Subscribe(to.NotifyUiItemsClick)
s.HeartBeat.Subscribe(to.NotifyHeartBeat)
s.DeviceLocation.Subscribe(to.NotifyDeviceLocation)
}

Expand Down
1 change: 0 additions & 1 deletion daemon/events/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ func (mockDaemonSubscriber) NotifyIpv6(bool) error { ret
func (mockDaemonSubscriber) NotifyDefaults(any) error { return nil }
func (mockDaemonSubscriber) NotifyMeshnet(bool) error { return nil }
func (mockDaemonSubscriber) NotifyUiItemsClick(events.UiItemsAction) error { return nil }
func (mockDaemonSubscriber) NotifyHeartBeat(int) error { return nil }
func (mockDaemonSubscriber) NotifyDeviceLocation(core.Insights) error { return nil }
func (mockDaemonSubscriber) NotifyLANDiscovery(bool) error { return nil }
func (mockDaemonSubscriber) NotifyVirtualLocation(bool) error { return nil }
Expand Down
10 changes: 6 additions & 4 deletions daemon/job_heartbeat.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package daemon

import (
"github.com/NordSecurity/nordvpn-linux/daemon/events"
"time"

"github.com/NordSecurity/nordvpn-linux/events"
)

// JobHeartBeat sends heart beats.
func JobHeartBeat(
timePeriod int,
events *events.Events,
publisher events.Publisher[time.Duration],
period time.Duration,
) func() {
return func() {
events.Service.HeartBeat.Publish(timePeriod)
publisher.Publish(period)
}
}
11 changes: 9 additions & 2 deletions daemon/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ import (
"google.golang.org/grpc/metadata"
)

func (r *RPC) StartJobs(statePublisher *state.StatePublisher) {
const (
heartBeatPeriod = time.Hour * 24
)

func (r *RPC) StartJobs(
statePublisher *state.StatePublisher,
heartBeatPublisher events.Publisher[time.Duration],
) {
// order of the jobs below matters
// servers job requires geo info and configs data to create server list
// TODO what if configs file is deleted just before servers job or disk is full?
Expand Down Expand Up @@ -51,7 +58,7 @@ func (r *RPC) StartJobs(statePublisher *state.StatePublisher) {
log.Println(internal.WarningPrefix, "job version schedule error:", err)
}

if _, err := r.scheduler.NewJob(gocron.DurationJob(24*time.Hour), gocron.NewTask(JobHeartBeat(1*24*60 /*minutes*/, r.events)), gocron.WithName("job heart beat")); err != nil {
if _, err := r.scheduler.NewJob(gocron.DurationJob(heartBeatPeriod), gocron.NewTask(JobHeartBeat(heartBeatPublisher, heartBeatPeriod), gocron.WithName("job heart beat"))); err != nil {
log.Println(internal.WarningPrefix, "job heart beat schedule error:", err)
}
if _, err := r.scheduler.NewJob(gocron.DurationJob(7*24*time.Hour), gocron.NewTask(func() {
Expand Down
33 changes: 24 additions & 9 deletions events/moose/moose.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ func (s *Subscriber) NotifyUiItemsClick(data events.UiItemsAction) error {
))
}

func (s *Subscriber) NotifyHeartBeat(timePeriodMinutes int) error {
return s.response(moose.NordvpnappSendServiceQualityStatusHeartbeat(int32(timePeriodMinutes)))
func (s *Subscriber) NotifyHeartBeat(period time.Duration) error {
return s.response(moose.NordvpnappSendServiceQualityStatusHeartbeat(int32(period.Minutes())))
}

func (s *Subscriber) NotifyDeviceLocation(insights core.Insights) error {
Expand All @@ -369,7 +369,11 @@ func (s *Subscriber) NotifyDeviceLocation(insights core.Insights) error {
func (s *Subscriber) NotifyNotify(bool) error { return nil }

func (s *Subscriber) NotifyMeshnet(data bool) error {
return s.response(moose.NordvpnappSetContextApplicationNordvpnappConfigUserPreferencesMeshnetEnabledValue(data))
if err := s.response(moose.NordvpnappSetContextApplicationNordvpnappConfigUserPreferencesMeshnetEnabledValue(data)); err != nil {
return err
}
// 0 duration indicates that this is not a periodic heart beat
return s.NotifyHeartBeat(time.Duration(0))
}

func (s *Subscriber) NotifyObfuscate(data bool) error {
Expand Down Expand Up @@ -499,7 +503,7 @@ func (s *Subscriber) NotifyConnect(data events.DataConnect) error {
default:
rule = moose.NordvpnappServerSelectionRuleRecommended
}
return s.response(moose.NordvpnappSendServiceQualityServersConnect(
if err := s.response(moose.NordvpnappSendServiceQualityServersConnect(
int32(data.DurationMs),
eventStatus,
moose.NordvpnappEventTriggerUser,
Expand All @@ -518,7 +522,13 @@ func (s *Subscriber) NotifyConnect(data events.DataConnect) error {
int32(-1),
"",
int32(-1),
))
)); err != nil {
return err
}
if data.EventStatus == events.StatusSuccess {
return s.response(moose.NordvpnappSetContextApplicationNordvpnappConfigCurrentStateIsOnVpnValue(true))
}
return nil
}
}

Expand All @@ -539,13 +549,15 @@ func (s *Subscriber) NotifyDisconnect(data events.DataDisconnect) error {
}

if s.connectionToMeshnetPeer {
return s.response(moose.NordvpnappSendServiceQualityServersDisconnectFromMeshnetDevice(
if err := s.response(moose.NordvpnappSendServiceQualityServersDisconnectFromMeshnetDevice(
int32(-1),
eventStatus,
moose.NordvpnappEventTriggerUser,
connectionTime, // seconds
int32(-1),
))
)); err != nil {
return err
}
} else {
var technology moose.NordvpnappVpnConnectionTechnology
switch data.Technology {
Expand Down Expand Up @@ -591,7 +603,7 @@ func (s *Subscriber) NotifyDisconnect(data events.DataDisconnect) error {
threatProtection = moose.NordvpnappOptBoolFalse
}

return s.response(moose.NordvpnappSendServiceQualityServersDisconnect(
if err := s.response(moose.NordvpnappSendServiceQualityServersDisconnect(
int32(-1),
eventStatus,
moose.NordvpnappEventTriggerUser,
Expand All @@ -610,8 +622,11 @@ func (s *Subscriber) NotifyDisconnect(data events.DataDisconnect) error {
connectionTime, // seconds
"",
int32(-1),
))
)); err != nil {
return err
}
}
return s.response(moose.NordvpnappSetContextApplicationNordvpnappConfigCurrentStateIsOnVpnValue(false))
Savolro marked this conversation as resolved.
Show resolved Hide resolved
}

func (s *Subscriber) NotifyRequestAPI(data events.DataRequestAPI) error {
Expand Down
Loading