DB Vacuum Button (#2312)

* Do the thing

* Retry

* fix types

---------

Co-authored-by: Brendan Allan <brendonovich@outlook.com>
This commit is contained in:
Oscar Beaumont 2024-04-13 02:15:56 +08:00 committed by GitHub
parent effee2140d
commit 8be59659d8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 71 additions and 20 deletions

View file

@ -7,11 +7,13 @@ use crate::{
};
use futures::StreamExt;
use prisma_client_rust::raw;
use sd_cache::{Model, Normalise, NormalisedResult, NormalisedResults};
use sd_file_ext::kind::ObjectKind;
use sd_p2p::RemoteIdentity;
use sd_prisma::prisma::{indexer_rule, object, statistics};
use tokio_stream::wrappers::IntervalStream;
use tracing::{info, warn};
use std::{
collections::{hash_map::Entry, HashMap},
@ -385,6 +387,27 @@ pub(crate) fn mount() -> AlphaRouter<Ctx> {
Ok(())
}),
)
.procedure(
"vaccumDb",
R.with2(library())
.mutation(|(_, library), _: ()| async move {
// We retry a few times because if the DB is being actively used, the vacuum will fail
for _ in 0..5 {
match library.db._execute_raw(raw!("VACUUM;")).exec().await {
Ok(_) => break,
Err(err) => {
warn!(
"Failed to vacuum DB for library '{}', retrying...: {err:#?}",
library.id
);
tokio::time::sleep(Duration::from_millis(500)).await;
}
}
}
info!("Successfully vacuumed DB for library '{}'", library.id);
Ok(())
}),
)
}
async fn update_statistics_loop(

View file

@ -88,31 +88,30 @@ const OperationGroup = ({ group }: { group: MessageGroup }) => {
function calculateGroups(messages: CRDTOperation[]) {
return messages.reduce<MessageGroup[]>((acc, op) => {
// TODO: fix Typescript
// const { data } = op;
const { data } = op;
// const id = JSON.stringify(op.record_id);
const id = JSON.stringify(op.record_id);
// const latest = (() => {
// const latest = acc[acc.length - 1];
const latest = (() => {
const latest = acc[acc.length - 1];
// if (!latest || latest.model !== op.model || latest.id !== id) {
// const group: MessageGroup = {
// model: op.model,
// id,
// messages: []
// };
if (!latest || latest.model !== op.model || latest.id !== id) {
const group: MessageGroup = {
model: op.model,
id,
messages: []
};
// acc.push(group);
acc.push(group);
// return group;
// } else return latest;
// })();
return group;
} else return latest;
})();
// latest.messages.push({
// data,
// timestamp: op.timestamp
// });
latest.messages.push({
data,
timestamp: op.timestamp
});
return acc;
}, []);

View file

@ -1,4 +1,10 @@
import { MaybeUndefined, useBridgeMutation, useLibraryContext, useZodForm } from '@sd/client';
import {
MaybeUndefined,
useBridgeMutation,
useLibraryContext,
useLibraryMutation,
useZodForm
} from '@sd/client';
import { Button, dialogManager, Form, InputField, Switch, Tooltip, z } from '@sd/ui';
import { useDebouncedFormWatch, useLocale } from '~/hooks';
@ -20,6 +26,7 @@ function toMaybeUndefined<T>(v: T | null | undefined): MaybeUndefined<T> {
export const Component = () => {
const { library } = useLibraryContext();
const editLibrary = useBridgeMutation('library.edit');
const vaccumLibrary = useLibraryMutation('library.vaccumDb');
const { t } = useLocale();
@ -94,6 +101,24 @@ export const Component = () => {
</div>
</Setting>
<Setting
mini
title={t('vaccum_library')}
description={t('vaccum_library_description')}
>
<div className="mt-2">
<Button
onClick={() => vaccumLibrary.mutate(null)}
disabled={vaccumLibrary.isLoading}
size="sm"
variant="gray"
className="whitespace-nowrap"
>
{t('vaccum')}
</Button>
</div>
</Setting>
<Setting
mini
title={t('delete_library')}

View file

@ -152,6 +152,9 @@
"export_library": "Export Library",
"export_library_coming_soon": "Export Library coming soon",
"export_library_description": "Export this library to a file.",
"vaccum": "Vaccum",
"vaccum_library": "Vaccum Library",
"vaccum_library_description": "Repack your database to free up unnecessary space.",
"extensions": "Extensions",
"extensions_description": "Install extensions to extend the functionality of this client.",
"fahrenheit": "Fahrenheit",

View file

@ -104,6 +104,7 @@ export type Procedures = {
{ key: "library.edit", input: EditLibraryArgs, result: null } |
{ key: "library.startActor", input: LibraryArgs<string>, result: null } |
{ key: "library.stopActor", input: LibraryArgs<string>, result: null } |
{ key: "library.vaccumDb", input: LibraryArgs<null>, result: null } |
{ key: "locations.addLibrary", input: LibraryArgs<LocationCreateArgs>, result: number | null } |
{ key: "locations.create", input: LibraryArgs<LocationCreateArgs>, result: number | null } |
{ key: "locations.delete", input: LibraryArgs<number>, result: null } |