Skip to content

Commit

Permalink
Add speed and ETA tracking to progress
Browse files Browse the repository at this point in the history
  • Loading branch information
mircearoata committed Dec 29, 2023
1 parent 45e34cc commit 7001f5f
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 11 deletions.
45 changes: 34 additions & 11 deletions backend/bindings/ficsitcli/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import (
"log/slog"
"time"

"github.com/dustin/go-humanize"
"github.com/pkg/errors"
"github.com/puzpuzpuz/xsync/v3"
"github.com/satisfactorymodding/ficsit-cli/cli"
"github.com/satisfactorymodding/ficsit-cli/utils"
ficsitUtils "github.com/satisfactorymodding/ficsit-cli/utils"
wailsRuntime "github.com/wailsapp/wails/v2/pkg/runtime"

"github.com/satisfactorymodding/SatisfactoryModManager/backend/utils"
)

func (f *FicsitCLI) validateInstall(installation *InstallationInfo, progressItem string) error {
Expand All @@ -21,8 +24,8 @@ func (f *FicsitCLI) validateInstall(installation *InstallationInfo, progressItem
defer f.setProgress(f.progress)

type modProgress struct {
downloadProgress utils.GenericProgress
extractProgress utils.GenericProgress
downloadProgress ficsitUtils.GenericProgress
extractProgress ficsitUtils.GenericProgress
downloading bool
complete bool
}
Expand All @@ -33,16 +36,19 @@ func (f *FicsitCLI) validateInstall(installation *InstallationInfo, progressItem
defer progressTicker.Stop()
defer close(done)

downloadProgressTracker := utils.NewProgressTracker(time.Second * 5)
extractProgressTracker := utils.NewProgressTracker(time.Second * 5)

go func() {
for {
select {
case <-done:
return
case <-progressTicker.C:
downloadBytesProgress := utils.GenericProgress{}
extractBytesProgress := utils.GenericProgress{}
downloadModsProgress := utils.GenericProgress{}
extractModsProgress := utils.GenericProgress{}
downloadBytesProgress := ficsitUtils.GenericProgress{}
extractBytesProgress := ficsitUtils.GenericProgress{}
downloadModsProgress := ficsitUtils.GenericProgress{}
extractModsProgress := ficsitUtils.GenericProgress{}

hasDownloading := false

Expand Down Expand Up @@ -73,19 +79,36 @@ func (f *FicsitCLI) validateInstall(installation *InstallationInfo, progressItem
return true
})

downloadProgressTracker.Add(downloadBytesProgress.Completed)
downloadProgressTracker.Total = downloadBytesProgress.Total
extractProgressTracker.Add(extractBytesProgress.Completed)
extractProgressTracker.Total = extractBytesProgress.Total

if hasDownloading {
if downloadBytesProgress.Total != 0 {
f.setProgress(&Progress{
Item: progressItem,
Message: fmt.Sprintf("Downloading %d/%d mods", downloadModsProgress.Completed, downloadModsProgress.Total),
Item: progressItem,
Message: fmt.Sprintf(
"Downloading %d/%d mods: %s/%s, %s/s, %s",
downloadModsProgress.Completed, downloadModsProgress.Total,
humanize.Bytes(uint64(downloadBytesProgress.Completed)), humanize.Bytes(uint64(downloadBytesProgress.Total)),
humanize.Bytes(uint64(downloadProgressTracker.Speed())),
downloadProgressTracker.ETA().Round(time.Second),
),
Progress: downloadBytesProgress.Percentage(),
})
}
} else {
if extractBytesProgress.Total != 0 {
f.setProgress(&Progress{
Item: progressItem,
Message: fmt.Sprintf("Extracting %d/%d mods", extractModsProgress.Completed, extractModsProgress.Total),
Item: progressItem,
Message: fmt.Sprintf(
"Extracting %d/%d mods: %s/%s, %s/s, %s",
extractModsProgress.Completed, extractModsProgress.Total,
humanize.Bytes(uint64(extractBytesProgress.Completed)), humanize.Bytes(uint64(extractBytesProgress.Total)),
humanize.Bytes(uint64(extractProgressTracker.Speed())),
extractProgressTracker.ETA().Round(time.Second),
),
Progress: extractBytesProgress.Percentage(),
})
}
Expand Down
62 changes: 62 additions & 0 deletions backend/utils/progress.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package utils

import (
"maps"
"time"
)

type ProgressTracker struct {
windowSize time.Duration
data map[time.Time]int64
Total int64
}

func NewProgressTracker(windowSize time.Duration) *ProgressTracker {
return &ProgressTracker{
windowSize: windowSize,
data: make(map[time.Time]int64),
}
}

func (pt *ProgressTracker) Add(value int64) {
pt.Total += value
pt.data[time.Now()] = value
pt.evict()
}

func (pt *ProgressTracker) Speed() float64 {
pt.evict()
var first, last time.Time
for t := range pt.data {
if first.IsZero() || t.Before(first) {
first = t
}
if last.IsZero() || t.After(last) {
last = t
}
}
firstData := pt.data[first]
lastData := pt.data[last]
return float64(lastData-firstData) / pt.windowSize.Seconds()
}

func (pt *ProgressTracker) ETA() time.Duration {
speed := pt.Speed()
if speed == 0 {
return 0
}
var latest time.Time
for t := range pt.data {
if latest.IsZero() || t.After(latest) {
latest = t
}
}
latestData := pt.data[latest]
return time.Duration(float64(pt.Total-latestData)/speed) * time.Second
}

func (pt *ProgressTracker) evict() {
maps.DeleteFunc(pt.data, func(t time.Time, _ int64) bool {
return time.Since(t) > pt.windowSize
})
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ toolchain go1.21.5
require (
github.com/Masterminds/semver/v3 v3.2.1
github.com/andygrunwald/vdf v1.1.0
github.com/dustin/go-humanize v1.0.1
github.com/lmittmann/tint v1.0.3
github.com/minio/selfupdate v0.6.0
github.com/mitchellh/go-ps v1.0.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
Expand Down

0 comments on commit 7001f5f

Please sign in to comment.