forked from github-starred/komodo
lock sync dir access
This commit is contained in:
@@ -6,7 +6,7 @@ use monitor_client::entities::{
|
||||
update::Log, CloneArgs, LatestCommit,
|
||||
};
|
||||
|
||||
use crate::config::core_config;
|
||||
use crate::{config::core_config, state::resource_sync_lock_cache};
|
||||
|
||||
pub async fn get_remote_resources(
|
||||
sync: &ResourceSync,
|
||||
@@ -37,6 +37,12 @@ pub async fn get_remote_resources(
|
||||
fs::create_dir_all(&config.sync_directory)
|
||||
.context("failed to create sync directory")?;
|
||||
|
||||
// lock simultaneous access to same directory
|
||||
let lock = resource_sync_lock_cache()
|
||||
.get_or_insert_default(&sync.id)
|
||||
.await;
|
||||
let _lock = lock.lock().await;
|
||||
|
||||
let mut logs =
|
||||
git::clone(clone_args, &config.sync_directory, github_token)
|
||||
.await
|
||||
|
||||
@@ -5,7 +5,7 @@ use monitor_client::entities::{
|
||||
procedure::ProcedureState, repo::RepoState,
|
||||
sync::ResourceSyncState,
|
||||
};
|
||||
use tokio::sync::OnceCell;
|
||||
use tokio::sync::{Mutex, OnceCell};
|
||||
|
||||
use crate::{
|
||||
auth::jwt::JwtClient,
|
||||
@@ -99,3 +99,11 @@ pub fn resource_sync_state_cache() -> &'static ResourceSyncStateCache
|
||||
OnceLock::new();
|
||||
RESOURCE_SYNC_STATE_CACHE.get_or_init(Default::default)
|
||||
}
|
||||
|
||||
pub type ResourceSyncLockCache = Cache<String, Arc<Mutex<()>>>;
|
||||
|
||||
pub fn resource_sync_lock_cache() -> &'static ResourceSyncLockCache {
|
||||
static RESOURCE_SYNC_LOCK_CACHE: OnceLock<ResourceSyncLockCache> =
|
||||
OnceLock::new();
|
||||
RESOURCE_SYNC_LOCK_CACHE.get_or_init(Default::default)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { useRead } from "@lib/hooks";
|
||||
import { RequiredResourceComponents } from "@types";
|
||||
import { Card, CardDescription, CardHeader, CardTitle } from "@ui/card";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@ui/card";
|
||||
import { FolderSync } from "lucide-react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { DeleteResource, NewResource } from "../common";
|
||||
@@ -10,14 +16,32 @@ import { ResourceSyncConfig } from "./config";
|
||||
import { useState } from "react";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@ui/tabs";
|
||||
import { ExecuteSync, RefreshSync } from "./actions";
|
||||
import { sanitizeOnlySpan, sync_no_changes } from "@lib/utils";
|
||||
import { Section } from "@components/layouts";
|
||||
|
||||
const useResourceSync = (id?: string) =>
|
||||
useRead("ListResourceSyncs", {}).data?.find((d) => d.id === id);
|
||||
|
||||
const PENDING_TYPE_KEYS: Array<[string, string]> = [
|
||||
["Server", "server_updates"],
|
||||
["Deployment", "deployment_updates"],
|
||||
["Build", "build_updates"],
|
||||
["Repo", "repo_updates"],
|
||||
["Procedure", "procedure_updates"],
|
||||
["Alerter", "alerter_updates"],
|
||||
["Builder", "builder_updates"],
|
||||
["Server Template", "server_template_updates"],
|
||||
["Resource Sync", "resource_sync_updates"],
|
||||
["Variable", "variable_updates"],
|
||||
["User Group", "user_group_updates"],
|
||||
];
|
||||
|
||||
const PendingOrConfig = ({ id }: { id: string }) => {
|
||||
const [view, setView] = useState("Pending");
|
||||
|
||||
const pendingDisabled = true;
|
||||
const sync = useRead("GetResourceSync", { sync: id }).data;
|
||||
|
||||
const pendingDisabled = !sync || sync_no_changes(sync);
|
||||
const currentView = view === "Pending" && pendingDisabled ? "Config" : view;
|
||||
|
||||
const tabsList = (
|
||||
@@ -35,10 +59,46 @@ const PendingOrConfig = ({ id }: { id: string }) => {
|
||||
<TabsContent value="Config">
|
||||
<ResourceSyncConfig id={id} titleOther={tabsList} />
|
||||
</TabsContent>
|
||||
<TabsContent value="Pending">
|
||||
<Section titleOther={tabsList}>
|
||||
{PENDING_TYPE_KEYS.map(([type, key]) => (
|
||||
<PendingView
|
||||
key={type}
|
||||
type={type}
|
||||
log={sync?.info?.pending?.[key]}
|
||||
/>
|
||||
))}
|
||||
</Section>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
);
|
||||
};
|
||||
|
||||
const PendingView = ({
|
||||
type,
|
||||
log,
|
||||
}: {
|
||||
type: string;
|
||||
log: string | undefined;
|
||||
}) => {
|
||||
if (!log) return;
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="flex-col">
|
||||
<CardTitle>{type} Updates</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<pre
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: sanitizeOnlySpan(log),
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export const ResourceSyncComponents: RequiredResourceComponents = {
|
||||
list_item: (id) => useResourceSync(id),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user