From 9caa66de548688f9448b84449221f281af62fe1c Mon Sep 17 00:00:00 2001 From: Lorenzo Ronzani Date: Sun, 16 Jun 2024 11:37:38 +0200 Subject: [PATCH] =?UTF-8?q?wip=20=F0=9F=9A=A7:=20=20Working=20on=20check?= =?UTF-8?q?=20deployments=20state=20during=20fetching=20phase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deps/candid/rdmx6-jaaaa-aaaaa-aaadq-cai.did | 5 - deps/pulled.json | 6 +- .../app/dashboard/new-deployment/page.tsx | 59 +++++----- frontend/app/dashboard/page.tsx | 102 +++++++++++------- 4 files changed, 98 insertions(+), 74 deletions(-) diff --git a/deps/candid/rdmx6-jaaaa-aaaaa-aaadq-cai.did b/deps/candid/rdmx6-jaaaa-aaaaa-aaadq-cai.did index f8aa40a..0164427 100644 --- a/deps/candid/rdmx6-jaaaa-aaaaa-aaadq-cai.did +++ b/deps/candid/rdmx6-jaaaa-aaaaa-aaadq-cai.did @@ -542,11 +542,6 @@ service : (opt InternetIdentityInit) -> { fetch_entries: () -> (vec BufferedArchiveEntry); acknowledge_entries: (sequence_number: nat64) -> (); - // Calls used for event stats housekeeping. - // Only callable by the canister itself. - prune_events_if_necessary: () -> (); - inject_prune_event: (timestamp: Timestamp) -> (); - // V2 API // WARNING: The following methods are experimental and may change in the future. diff --git a/deps/pulled.json b/deps/pulled.json index 9e2d061..c832cba 100644 --- a/deps/pulled.json +++ b/deps/pulled.json @@ -2,12 +2,12 @@ "canisters": { "rdmx6-jaaaa-aaaaa-aaadq-cai": { "name": "internet_identity", - "wasm_hash": "764cff569a98a3c4d54cba6750fda63f554fc53e7d42a6365d9bdec3280d63c3", - "wasm_hash_download": "764cff569a98a3c4d54cba6750fda63f554fc53e7d42a6365d9bdec3280d63c3", + "wasm_hash": "01797eac7db02126e7cb507e2f3134e2d7b5154289808fdc2c8c03d1fc2dc60e", + "wasm_hash_download": "01797eac7db02126e7cb507e2f3134e2d7b5154289808fdc2c8c03d1fc2dc60e", "init_guide": "Use '(null)' for sensible defaults. See the candid interface for more details.", "init_arg": null, "candid_args": "(opt InternetIdentityInit)", "gzip": true } } -} +} \ No newline at end of file diff --git a/frontend/app/dashboard/new-deployment/page.tsx b/frontend/app/dashboard/new-deployment/page.tsx index 930851a..8dee3e1 100644 --- a/frontend/app/dashboard/new-deployment/page.tsx +++ b/frontend/app/dashboard/new-deployment/page.tsx @@ -1,33 +1,33 @@ "use client"; -import { BackButton } from "@/components/back-button"; -import { useToast } from "@/components/ui/use-toast"; -import { useDeploymentContext } from "@/contexts/DeploymentContext"; +import {BackButton} from "@/components/back-button"; +import {useToast} from "@/components/ui/use-toast"; +import {useDeploymentContext} from "@/contexts/DeploymentContext"; import { type OnWsErrorCallback, type OnWsMessageCallback, type OnWsOpenCallback, useIcContext, } from "@/contexts/IcContext"; -import type { DeploymentParams, DeploymentState } from "@/declarations/backend.did"; -import { extractDeploymentCreated } from "@/helpers/deployment"; -import { extractOk } from "@/helpers/result"; -import { sendManifestToProvider } from "@/services/deployment"; -import { useRouter } from "next/navigation"; -import { useCallback, useEffect, useMemo, useState } from "react"; -import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; -import { AlertCircle } from "lucide-react"; -import { displayE8sAsIcp, icpToE8s } from "@/helpers/ui"; -import { Spinner } from "@/components/spinner"; -import { NewDeploymentForm } from "@/components/new-deployment-form"; -import { transferE8sToBackend } from "@/services/backend"; +import type {DeploymentParams, DeploymentState} from "@/declarations/backend.did"; +import {extractOk} from "@/helpers/result"; +import {useRouter} from "next/navigation"; +import {useCallback, useEffect, useMemo, useState} from "react"; +import {Alert, AlertDescription, AlertTitle} from "@/components/ui/alert"; +import {AlertCircle} from "lucide-react"; +import {displayE8sAsIcp, icpToE8s} from "@/helpers/ui"; +import {Spinner} from "@/components/spinner"; +import {NewDeploymentForm} from "@/components/new-deployment-form"; +import {transferE8sToBackend} from "@/services/backend"; +import {extractDeploymentCreated} from "@/helpers/deployment"; +import {sendManifestToProvider} from "@/services/deployment"; const FETCH_DEPLOYMENT_PRICE_INTERVAL_MS = 30_000; // 30 seconds export default function NewDeployment() { const router = useRouter(); - const { backendActor, openWs, closeWs, setWsCallbacks, ledgerCanister, ledgerData, refreshLedgerData } = useIcContext(); - const { tlsCertificateData, loadOrCreateCertificate, fetchDeployments } = + const {backendActor, openWs, closeWs, setWsCallbacks, ledgerCanister, ledgerData, refreshLedgerData} = useIcContext(); + const {tlsCertificateData, loadOrCreateCertificate, fetchDeployments} = useDeploymentContext(); const [isSubmitting, setIsSubmitting] = useState(false); const [isDeploying, setIsDeploying] = useState(false); @@ -38,12 +38,12 @@ export default function NewDeployment() { const [deploymentE8sPrice, setDeploymentE8sPrice] = useState(null); const [fetchDeploymentPriceInterval, setFetchDeploymentPriceInterval] = useState(null); const userHasEnoughBalance = useMemo(() => - ledgerData.balanceE8s !== null && deploymentE8sPrice !== null && ledgerData.balanceE8s > deploymentE8sPrice, + ledgerData.balanceE8s !== null && deploymentE8sPrice !== null && ledgerData.balanceE8s > deploymentE8sPrice, [ledgerData.balanceE8s, deploymentE8sPrice] ); const [paymentStatus, setPaymentStatus] = useState(null); const [deploymentParams, setDeploymentParams] = useState(null); - const { toast } = useToast(); + const {toast} = useToast(); const toastError = useCallback( (message: string) => { @@ -113,7 +113,7 @@ export default function NewDeployment() { const res = await backendActor.create_deployment(deploymentParams); const deploymentId = extractOk(res); console.log("deployment id", deploymentId); - setDeploymentSteps([{ Initialized: null }]); + setDeploymentSteps([{Initialized: null}]); }; setIsDeploying(true); @@ -157,12 +157,15 @@ export default function NewDeployment() { try { if ("LeaseCreated" in deploymentUpdate.update) { - const { manifest_sorted_json, dseq } = extractDeploymentCreated( + // closeWs(); + // return; + + const {manifest_sorted_json, dseq} = extractDeploymentCreated( deploymentSteps.find((el) => el.hasOwnProperty("DeploymentCreated") )! ); - const { provider_url } = deploymentUpdate.update.LeaseCreated; + const {provider_url} = deploymentUpdate.update.LeaseCreated; const manifestUrl = new URL( `/deployment/${dseq}/manifest`, @@ -350,7 +353,7 @@ export default function NewDeployment() { return (
- +

Create Deployment

@@ -369,13 +372,13 @@ export default function NewDeployment() { Price (est.): {deploymentE8sPrice !== null ? ( -
~{displayE8sAsIcp(deploymentE8sPrice, { maximumFractionDigits: 6 })}
+
~{displayE8sAsIcp(deploymentE8sPrice, {maximumFractionDigits: 6})}
) : ( - + )} {(!(isSubmitting || isDeploying) && (deploymentE8sPrice !== null) && !userHasEnoughBalance) && ( - + Insufficient balance

Please top up your account.

@@ -408,13 +411,13 @@ export default function NewDeployment() { {idx + 1}. {el}

))} - {isDeploying && } + {isDeploying && }
)} {Boolean(deploymentError) && ( - + Deployment Error

{deploymentError}

diff --git a/frontend/app/dashboard/page.tsx b/frontend/app/dashboard/page.tsx index 2ac85d0..e391d38 100644 --- a/frontend/app/dashboard/page.tsx +++ b/frontend/app/dashboard/page.tsx @@ -1,22 +1,11 @@ "use client"; import Tier from "@/components/Tier"; -import { LoadingButton } from "@/components/loading-button"; -import { Spinner } from "@/components/spinner"; -import { Button } from "@/components/ui/button"; -import { - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, -} from "@/components/ui/card"; -import { - Collapsible, - CollapsibleContent, - CollapsibleTrigger, -} from "@/components/ui/collapsible"; +import {LoadingButton} from "@/components/loading-button"; +import {Spinner} from "@/components/spinner"; +import {Button} from "@/components/ui/button"; +import {Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle,} from "@/components/ui/card"; +import {Collapsible, CollapsibleContent, CollapsibleTrigger,} from "@/components/ui/collapsible"; import { Dialog, DialogContent, @@ -26,10 +15,10 @@ import { DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; -import { useToast } from "@/components/ui/use-toast"; -import { useDeploymentContext } from "@/contexts/DeploymentContext"; -import { useIcContext } from "@/contexts/IcContext"; -import { type Deployment } from "@/declarations/backend.did"; +import {useToast} from "@/components/ui/use-toast"; +import {useDeploymentContext} from "@/contexts/DeploymentContext"; +import {useIcContext} from "@/contexts/IcContext"; +import {type Deployment} from "@/declarations/backend.did"; import { extractDeploymentCreated, extractLeaseCreated, @@ -41,17 +30,17 @@ import { isDeploymentClosed, isDeploymentFailed, } from "@/helpers/deployment"; -import { displayIcp } from "@/helpers/ui"; -import { queryLeaseStatus } from "@/services/deployment"; -import { DeploymentTier } from "@/types/deployment"; -import { ChevronsUpDown } from "lucide-react"; -import { useRouter } from "next/navigation"; -import { useCallback, useEffect, useState } from "react"; +import {displayIcp} from "@/helpers/ui"; +import {queryLeaseStatus, sendManifestToProvider} from "@/services/deployment"; +import {DeploymentTier} from "@/types/deployment"; +import {ChevronsUpDown} from "lucide-react"; +import {useRouter} from "next/navigation"; +import {useCallback, useEffect, useState} from "react"; export default function Dashboard() { const router = useRouter(); - const { isLoggedIn, backendActor } = useIcContext(); - const { deployments, fetchDeployments, loadOrCreateCertificate } = + const {isLoggedIn, backendActor} = useIcContext(); + const {deployments, fetchDeployments, loadOrCreateCertificate} = useDeploymentContext(); const [isClosingDeployment, setIsClosingDeployment] = useState(false); const [dialogDeploymentId, setDialogDeploymentId] = useState(); @@ -59,7 +48,7 @@ export default function Dashboard() { const [isFetchingStatus, setIsFetchingStatus] = useState(false); const [leaseStatusData, setLeaseStatusData] = useState>(); - const { toast } = useToast(); + const {toast} = useToast(); const handleNewDeployment = useCallback(async () => { router.push("/dashboard/new-deployment"); @@ -92,10 +81,10 @@ export default function Dashboard() { try { const certData = await loadOrCreateCertificate(backendActor!); const updates = deployment.state_history.map(([_, d]) => d); - const { dseq } = extractDeploymentCreated( + const {dseq} = extractDeploymentCreated( updates.find((el) => el.hasOwnProperty("DeploymentCreated"))! ); - const { provider_url } = extractLeaseCreated( + const {provider_url} = extractLeaseCreated( updates.find((el) => el.hasOwnProperty("LeaseCreated"))! ); @@ -129,6 +118,41 @@ export default function Dashboard() { } }, [isLoggedIn, fetchDeployments, backendActor]); + useEffect(() => { + checkDeploymentState(); + }, [deployments]); + + const checkDeploymentState = useCallback(async () => { + for (const deployment of deployments) { + const lastState = deployment.deployment.state_history[deployment.deployment.state_history.length - 1][1]; + if ("LeaseCreated" in lastState) { + try { + const cert = await loadOrCreateCertificate(backendActor!); + + const deploymentCreatedState = deployment.deployment.state_history.find(([_, state]) => "DeploymentCreated" in state)!; + const {manifest_sorted_json, dseq} = extractDeploymentCreated( + deploymentCreatedState[1] + ); + + const {provider_url} = lastState.LeaseCreated; + + const manifestUrl = new URL( + `/deployment/${dseq}/manifest`, + provider_url + ); + + await sendManifestToProvider( + manifestUrl.toString(), + manifest_sorted_json, + cert! + ); + } catch (e) { + console.error(e); + } + } + } + }, [deployments]); + return (
@@ -144,7 +168,9 @@ export default function Dashboard() { {el.deployment.params.name} -
{el.id}
+ +
{el.id}
+
@@ -163,17 +189,17 @@ export default function Dashboard() { Tier: {/* TODO: display the actual deployment tier */}
- +
Price: -
{displayIcp(el.deployment.icp_price, { maximumFractionDigits: 6 })}
+
{displayIcp(el.deployment.icp_price, {maximumFractionDigits: 6})}
Status history - + {el.deployment.state_history.map((item, i) => ( @@ -209,7 +235,7 @@ export default function Dashboard() { Deployment status {isFetchingStatus ? ( - + ) : ( Boolean(leaseStatusData) && ( @@ -237,9 +263,9 @@ export default function Dashboard() { Are you sure? Deployment id to close: -
+
{el.id} -
+
This action cannot be undone.