From 30edf4ea8eb1e694a0af2f9ec25ffb133c19d0c7 Mon Sep 17 00:00:00 2001
From: Andrey Sobolev <haiodo@users.noreply.github.com>
Date: Tue, 24 Dec 2024 20:16:45 +0700
Subject: [PATCH] Fix Backup info size display (#7540)

---
 packages/core/src/backup.ts                   |  2 ++
 packages/core/src/server.ts                   |  2 ++
 .../src/components/AdminWorkspaces.svelte     | 12 ++++++++---
 plugins/login-resources/src/utils.ts          |  1 +
 .../src/components/SelectWorkspaceMenu.svelte |  5 ++++-
 server/backup/src/backup.ts                   | 21 ++++++++++++-------
 server/core/src/storage.ts                    |  7 ++++++-
 7 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/packages/core/src/backup.ts b/packages/core/src/backup.ts
index 7e052bb97c..b7be7cb074 100644
--- a/packages/core/src/backup.ts
+++ b/packages/core/src/backup.ts
@@ -10,6 +10,8 @@ export interface DocChunk {
   idx: number
   // _id => hash mapping
   docs: DocInfo[]
+
+  size?: number // Estimated size of the chunk data
   finished: boolean
 }
 
diff --git a/packages/core/src/server.ts b/packages/core/src/server.ts
index 5279bc30f9..5a482642d4 100644
--- a/packages/core/src/server.ts
+++ b/packages/core/src/server.ts
@@ -25,6 +25,8 @@ import type { WorkspaceIdWithUrl } from './utils'
 export interface DocInfo {
   id: string
   hash: string
+
+  size?: number
 }
 /**
  * @public
diff --git a/plugins/login-resources/src/components/AdminWorkspaces.svelte b/plugins/login-resources/src/components/AdminWorkspaces.svelte
index 9325943a65..6c90755d23 100644
--- a/plugins/login-resources/src/components/AdminWorkspaces.svelte
+++ b/plugins/login-resources/src/components/AdminWorkspaces.svelte
@@ -1,5 +1,5 @@
 <script lang="ts">
-  import { groupByArray, type BaseWorkspaceInfo } from '@hcengineering/core'
+  import { groupByArray, isActiveMode, type BaseWorkspaceInfo } from '@hcengineering/core'
   import { getEmbeddedLabel } from '@hcengineering/platform'
   import { isAdminUser } from '@hcengineering/presentation'
   import {
@@ -84,6 +84,9 @@
 {#if isAdmin}
   <div class="anticrm-panel flex-row flex-grow p-5">
     <div class="fs-title p-3">Workspaces administration panel</div>
+    <div class="fs-title p-3">
+      Workspaces: {workspaces.length} active: {workspaces.filter((it) => isActiveMode(it.mode)).length}
+    </div>
     <div class="fs-title p-3 flex-no-shrink">
       <SearchEdit bind:value={search} width={'100%'} />
     </div>
@@ -174,7 +177,7 @@
                       </span>
 
                       <span class="label overflow-label" style:width={'10rem'}>
-                        {workspace.mode}
+                        {workspace.mode ?? '-'}
                       </span>
 
                       <span class="label overflow-label" style:width={'2rem'}>
@@ -191,7 +194,10 @@
                       </span>
                       <span class="flex flex-between" style:width={'5rem'}>
                         {#if workspace.backupInfo != null}
-                          {@const sz = workspace.backupInfo.dataSize + workspace.backupInfo.blobsSize}
+                          {@const sz = Math.max(
+                            workspace.backupInfo.backupSize,
+                            workspace.backupInfo.dataSize + workspace.backupInfo.blobsSize
+                          )}
                           {@const szGb = Math.round((sz * 100) / 1024) / 100}
                           {#if szGb > 0}
                             {Math.round((sz * 100) / 1024) / 100}Gb
diff --git a/plugins/login-resources/src/utils.ts b/plugins/login-resources/src/utils.ts
index e34f8936e8..527a0f3491 100644
--- a/plugins/login-resources/src/utils.ts
+++ b/plugins/login-resources/src/utils.ts
@@ -215,6 +215,7 @@ function getWorkspaceSize (it: Pick<Workspace, 'backupInfo'>): number {
   let sz = 0
   sz += it.backupInfo?.dataSize ?? 0
   sz += it.backupInfo?.blobsSize ?? 0
+  sz += it.backupInfo?.backupSize ?? 0
   return sz
 }
 
diff --git a/plugins/workbench-resources/src/components/SelectWorkspaceMenu.svelte b/plugins/workbench-resources/src/components/SelectWorkspaceMenu.svelte
index a0b9f99734..537e00a3d2 100644
--- a/plugins/workbench-resources/src/components/SelectWorkspaceMenu.svelte
+++ b/plugins/workbench-resources/src/components/SelectWorkspaceMenu.svelte
@@ -189,7 +189,10 @@
                   {#if isAdmin && ws.lastVisit != null && ws.lastVisit !== 0}
                     <div class="text-sm">
                       {#if ws.backupInfo != null}
-                        {@const sz = ws.backupInfo.dataSize + ws.backupInfo.blobsSize}
+                        {@const sz = Math.max(
+                          ws.backupInfo.backupSize,
+                          ws.backupInfo.dataSize + ws.backupInfo.blobsSize
+                        )}
                         {@const szGb = Math.round((sz * 100) / 1024) / 100}
                         {#if szGb > 0}
                           {Math.round((sz * 100) / 1024) / 100}Gb -
diff --git a/server/backup/src/backup.ts b/server/backup/src/backup.ts
index bdd7badcf2..dc2c4d544d 100644
--- a/server/backup/src/backup.ts
+++ b/server/backup/src/backup.ts
@@ -897,6 +897,12 @@ export async function backup (
       while (true) {
         try {
           const currentChunk = await ctx.with('loadChunk', {}, () => connection.loadChunk(domain, idx))
+          if (domain === DOMAIN_BLOB) {
+            result.blobsSize += currentChunk.size ?? 0
+          } else {
+            result.dataSize += currentChunk.size ?? 0
+          }
+
           idx = currentChunk.idx
           ops++
 
@@ -1152,12 +1158,6 @@ export async function backup (
             break
           }
 
-          if (domain === DOMAIN_BLOB) {
-            result.blobsSize += (d as Blob).size
-          } else {
-            result.dataSize += JSON.stringify(d).length
-          }
-
           function processChanges (d: Doc, error: boolean = false): void {
             processed++
             // Move processed document to processedChanges
@@ -1777,6 +1777,7 @@ export async function restore (
     let loaded = 0
     let el = 0
     let chunks = 0
+    let dataSize = 0
     try {
       while (true) {
         if (opt.progress !== undefined) {
@@ -1784,6 +1785,7 @@ export async function restore (
         }
         const st = Date.now()
         const it = await connection.loadChunk(c, idx)
+        dataSize += it.size ?? 0
         chunks++
 
         idx = it.idx
@@ -1808,7 +1810,12 @@ export async function restore (
         await connection.closeChunk(idx)
       }
     }
-    ctx.info('loaded', { loaded, workspace: workspaceId.name })
+    ctx.info('loaded', {
+      domain: c,
+      loaded,
+      workspace: workspaceId.name,
+      dataSize: Math.round((dataSize / (1024 * 1024)) * 100) / 100
+    })
     ctx.info('\tcompare documents', {
       size: changeset.size,
       serverSize: serverChangeset.size,
diff --git a/server/core/src/storage.ts b/server/core/src/storage.ts
index d2564d82b9..7ad615707c 100644
--- a/server/core/src/storage.ts
+++ b/server/core/src/storage.ts
@@ -52,6 +52,7 @@ export class BackupClientOps {
     return ctx.with('load-chunk', {}, async (ctx) => {
       idx = idx ?? this.idIndex++
       let chunk: ChunkInfo | undefined = this.chunkInfo.get(idx)
+      let size = 0
       if (chunk !== undefined) {
         chunk.index++
         if (chunk.finished === undefined || chunk.finished) {
@@ -74,12 +75,16 @@ export class BackupClientOps {
           break
         }
         docs.push(..._docs)
+        for (const d of _docs) {
+          size += d.size ?? 0
+        }
       }
 
       return {
         idx,
         docs,
-        finished: chunk.finished
+        finished: chunk.finished,
+        size
       }
     })
   }