Add Provisioned project state (#7658)

- Closes https://github.com/enso-org/cloud-v2/issues/647
- Add handling for `Provisioned` project state to frontend

- Also fixes bug causing cloud project loading message to not disappear (oops...)

# Important Notes
- sometimes the editor opens fine, but the websocket times out
- when checking requests, I don't see a request that returns `Provisioned`, so I can't be 100% sure that the handling for the `Provisioned` state actually works
This commit is contained in:
somebody1234 2023-08-28 21:05:41 +10:00 committed by GitHub
parent b8edf6a358
commit f6225882ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 7 additions and 26 deletions

View File

@ -98,6 +98,7 @@ export enum ProjectState {
created = 'Created',
new = 'New',
openInProgress = 'OpenInProgress',
provisioned = 'Provisioned',
opened = 'Opened',
closed = 'Closed',
/** A frontend-specific state, representing a project that should be displayed as

View File

@ -31,6 +31,7 @@ const REMOTE_SPINNER_STATE: Record<backendModule.ProjectState, spinner.SpinnerSt
[backendModule.ProjectState.new]: spinner.SpinnerState.initial,
[backendModule.ProjectState.placeholder]: spinner.SpinnerState.loadingSlow,
[backendModule.ProjectState.openInProgress]: spinner.SpinnerState.loadingSlow,
[backendModule.ProjectState.provisioned]: spinner.SpinnerState.loadingSlow,
[backendModule.ProjectState.opened]: spinner.SpinnerState.done,
}
/** The corresponding {@link SpinnerState} for each {@link backendModule.ProjectState},
@ -42,6 +43,7 @@ const LOCAL_SPINNER_STATE: Record<backendModule.ProjectState, spinner.SpinnerSta
[backendModule.ProjectState.new]: spinner.SpinnerState.initial,
[backendModule.ProjectState.placeholder]: spinner.SpinnerState.loadingMedium,
[backendModule.ProjectState.openInProgress]: spinner.SpinnerState.loadingMedium,
[backendModule.ProjectState.provisioned]: spinner.SpinnerState.loadingMedium,
[backendModule.ProjectState.opened]: spinner.SpinnerState.done,
}
@ -116,6 +118,7 @@ export default function ProjectIcon(props: ProjectIconProps) {
const abortController = new AbortController()
setOpenProjectAbortController(abortController)
await remoteBackend.waitUntilProjectIsReady(backend, item, abortController)
setToastId(null)
if (!abortController.signal.aborted) {
setState(oldState =>
oldState === backendModule.ProjectState.openInProgress
@ -296,6 +299,7 @@ export default function ProjectIcon(props: ProjectIconProps) {
</button>
)
case backendModule.ProjectState.openInProgress:
case backendModule.ProjectState.provisioned:
case backendModule.ProjectState.placeholder:
return (
<button

View File

@ -40,8 +40,6 @@ function responseIsSuccessful(response: Response) {
/** The interval between requests checking whether the IDE is ready. */
const CHECK_STATUS_INTERVAL_MS = 5000
/** The interval between requests checking whether the VM is ready. */
const CHECK_RESOURCES_INTERVAL_MS = 1000
/** Return a {@link Promise} that resolves only when a project is ready to open. */
export async function waitUntilProjectIsReady(
@ -52,6 +50,7 @@ export async function waitUntilProjectIsReady(
let project = await backend.getProjectDetails(item.id, item.title)
if (
project.state.type !== backendModule.ProjectState.openInProgress &&
project.state.type !== backendModule.ProjectState.provisioned &&
project.state.type !== backendModule.ProjectState.opened
) {
await backend.openProject(item.id, null, item.title)
@ -68,20 +67,6 @@ export async function waitUntilProjectIsReady(
nextCheckTimestamp = Number(new Date()) + CHECK_STATUS_INTERVAL_MS
project = await backend.getProjectDetails(item.id, item.title)
}
nextCheckTimestamp = 0
while (!abortController.signal.aborted) {
try {
await new Promise<void>(resolve => {
const delayMs = nextCheckTimestamp - Number(new Date())
setTimeout(resolve, Math.max(0, delayMs))
})
nextCheckTimestamp = Number(new Date()) + CHECK_RESOURCES_INTERVAL_MS
await backend.checkResources(item.id, item.title)
break
} catch {
// Ignored.
}
}
}
// =============
@ -355,18 +340,9 @@ export class RemoteBackend extends backendModule.Backend {
type: asset.id.match(/^(.+?)-/)?.[1],
} as backendModule.AnyAsset)
)
.map(asset =>
asset.type === backendModule.AssetType.project &&
asset.projectState.type === backendModule.ProjectState.opened
? {
...asset,
projectState: { type: backendModule.ProjectState.openInProgress },
}
: asset
)
.map(asset => ({
...asset,
permissions: (asset.permissions ?? []).sort(
permissions: [...(asset.permissions ?? [])].sort(
backendModule.compareUserPermissions
),
}))