aboutsummaryrefslogtreecommitdiff
path: root/xmpp/gateway
diff options
context:
space:
mode:
authorBohdan Horbeshko <bodqhrohro@gmail.com>2022-04-01 04:42:12 +0300
committerBohdan Horbeshko <bodqhrohro@gmail.com>2022-04-01 04:42:12 +0300
commit17afd3f8c7a016d5103be949990efb695de865b5 (patch)
tree5fa9a3a0cbf418b7e4913e9aef2df3d5981030f3 /xmpp/gateway
parent5c238db1da48e6c1d51a3d00f6a661f99de03784 (diff)
Limit the file storage by an optional quota
Diffstat (limited to 'xmpp/gateway')
-rw-r--r--xmpp/gateway/storage.go89
1 files changed, 89 insertions, 0 deletions
diff --git a/xmpp/gateway/storage.go b/xmpp/gateway/storage.go
new file mode 100644
index 0000000..a3fad79
--- /dev/null
+++ b/xmpp/gateway/storage.go
@@ -0,0 +1,89 @@
+package gateway
+
+import (
+ "io/ioutil"
+ "os"
+ "sort"
+ "sync"
+
+ log "github.com/sirupsen/logrus"
+)
+
+// StorageQuota is a value from config parsed to bytes number
+var StorageQuota uint64
+// CachedStorageSize estimates the storage size between full rescans
+var CachedStorageSize uint64
+var StorageLock = sync.Mutex{}
+
+// MeasureStorageSize replaces the estimated storage size with relevant data from the filesystem
+func MeasureStorageSize(path string) {
+ dents, err := ioutil.ReadDir(path)
+ if err != nil {
+ return
+ }
+
+ var total uint64
+ for _, fi := range dents {
+ if !fi.IsDir() {
+ total += uint64(fi.Size())
+ }
+ }
+
+ if total != CachedStorageSize {
+ if CachedStorageSize > 0 {
+ log.Warnf("Correcting cached storage size: was %v, actually %v", CachedStorageSize, total)
+ }
+ CachedStorageSize = total
+ }
+}
+
+// CleanOldFiles purges the oldest files in a directory that exceed the limit
+func CleanOldFiles(path string, limit uint64) {
+ dents, err := ioutil.ReadDir(path)
+ if err != nil {
+ return
+ }
+
+ var total uint64
+ for _, fi := range dents {
+ if !fi.IsDir() {
+ total += uint64(fi.Size())
+ }
+ }
+
+ // sort by time
+ sort.Slice(dents, func(i int, j int) bool {
+ return dents[i].ModTime().Before(dents[j].ModTime())
+ })
+
+ // purge
+ if total > limit {
+ toPurge := total - limit
+
+ var purgedAmount uint64
+ var purgedCount uint64
+
+ for _, fi := range dents {
+ if !fi.IsDir() {
+ err = os.Remove(path + string(os.PathSeparator) + fi.Name())
+ if err != nil {
+ log.Errorf("Couldn't remove %v: %v", fi.Name(), err)
+ continue
+ }
+
+ purgedAmount += uint64(fi.Size())
+ purgedCount += 1
+ if purgedAmount >= toPurge {
+ break
+ }
+ }
+ }
+
+ log.Infof("Cleaned %v bytes of %v old files", purgedAmount, purgedCount)
+ if CachedStorageSize > purgedAmount {
+ CachedStorageSize -= purgedAmount
+ } else {
+ CachedStorageSize = 0
+ }
+ }
+}