Skip to content

Commit

Permalink
[webapp] Introduce new instance phase "building" (part I, back- and f…
Browse files Browse the repository at this point in the history
…orwards-compatible)
  • Loading branch information
Andrew Farries authored and roboquat committed Apr 27, 2022
1 parent f3f0aef commit 35e2178
Show file tree
Hide file tree
Showing 9 changed files with 35 additions and 16 deletions.
4 changes: 3 additions & 1 deletion components/dashboard/src/components/PrebuildLogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,10 @@ export default function PrebuildLogs(props: PrebuildLogsProps) {
useEffect(() => {
switch (workspaceInstance?.status.phase) {
// Preparing means that we haven't actually started the workspace instance just yet, but rather
// are still preparing for launch. This means we're building the Docker image for the workspace.
// are still preparing for launch.
case "preparing":
// Building means we're building the Docker image for the workspace so the workspace hasn't started yet.
case "building":
case "stopped":
getGitpodService().server.watchWorkspaceImageBuildLogs(workspace!.id);
break;
Expand Down
7 changes: 4 additions & 3 deletions components/dashboard/src/start/StartWorkspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ export default class StartWorkspace extends React.Component<StartWorkspaceProps,
return;
}

if (workspaceInstance.status.phase === "preparing") {
if (workspaceInstance.status.phase === "building" || workspaceInstance.status.phase == "preparing") {
this.setState({ hasImageBuildLogs: true });
}

Expand Down Expand Up @@ -402,10 +402,11 @@ export default class StartWorkspace extends React.Component<StartWorkspaceProps,
// a workspace. This phase is usually accompanied by an error.
case "unknown":
break;

// Preparing means that we haven't actually started the workspace instance just yet, but rather
// are still preparing for launch. This means we're building the Docker image for the workspace.
// are still preparing for launch.
case "preparing":
// Building means we're building the Docker image for the workspace.
case "building":
return <ImageBuildView workspaceId={this.state.workspaceInstance.workspaceId} />;

// Pending means the workspace does not yet consume resources in the cluster, but rather is looking for
Expand Down
15 changes: 8 additions & 7 deletions components/gitpod-protocol/src/gitpod-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -530,13 +530,14 @@ const hasWindow = typeof window !== "undefined";
const phasesOrder: Record<WorkspaceInstancePhase, number> = {
unknown: 0,
preparing: 1,
pending: 2,
creating: 3,
initializing: 4,
running: 5,
interrupted: 6,
stopping: 7,
stopped: 8,
building: 2,
pending: 3,
creating: 4,
initializing: 5,
running: 6,
interrupted: 7,
stopping: 8,
stopped: 9,
};
export class WorkspaceInstanceUpdateListener {
private readonly onDidChangeEmitter = new Emitter<void>();
Expand Down
6 changes: 5 additions & 1 deletion components/gitpod-protocol/src/workspace-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,13 @@ export type WorkspaceInstancePhase =
| "unknown"

// Preparing means that we haven't actually started the workspace instance just yet, but rather
// are still preparing for launch. This means we're building the Docker image for the workspace.
// are still preparing for launch.
| "preparing"

// Building means that we are building the Docker image for the workspace. A workspace will enter this phase only
// if an image build is required for that workspace.
| "building"

// Pending means the workspace does not yet consume resources in the cluster, but rather is looking for
// some space within the cluster. If for example the cluster needs to scale up to accomodate the
// workspace, the workspace will be in Pending state until that happened.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
when (update.status.phase) {
"preparing" -> {
phaseMessage.text = "Preparing"
statusMessage.text = "Preparing workspace..."
}
"building" -> {
phaseMessage.text = "Building"
statusMessage.text = "Building workspace image..."
}
"pending" -> {
Expand Down
4 changes: 2 additions & 2 deletions components/server/src/workspace/gitpod-server-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1541,8 +1541,8 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
await new Promise((resolve) => setTimeout(resolve, 2000));

const wsi = await this.workspaceDb.trace(ctx).findInstanceById(instance.id);
if (!wsi || wsi.status.phase !== "preparing") {
log.debug(logCtx, `imagebuild logs: instance is not/no longer in 'preparing' state`, {
if (!wsi || (wsi.status.phase !== "preparing" && wsi.status.phase !== "building")) {
log.debug(logCtx, `imagebuild logs: instance is not/no longer in 'building' state`, {
phase: wsi?.status.phase,
});
return;
Expand Down
1 change: 1 addition & 0 deletions components/server/src/workspace/headless-log-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ export class HeadlessLogService {
function isSupervisorAvailableSoon(wsi: WorkspaceInstance): boolean {
switch (wsi.status.phase) {
case "creating":
case "building":
case "preparing":
case "initializing":
case "pending":
Expand Down
2 changes: 1 addition & 1 deletion components/ws-manager-bridge/src/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export class WorkspaceManagerBridge implements Disposable {
// Still, listen to all updates, generate/derive new state and distribute it locally!
startStatusUpdateHandler(false);

// emulate WorkspaceInstance updates for all Workspaces in the "preparing" phase in this cluster
// emulate WorkspaceInstance updates for all Workspaces in the "preparing" or "building" phase in this cluster
const updateEmulator = this.preparingUpdateEmulatorFactory() as PreparingUpdateEmulator;
this.disposables.push(updateEmulator);
updateEmulator.start(cluster.name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ export class PreparingUpdateEmulator implements Disposable {
const span = TraceContext.startSpan("preparingUpdateEmulatorRun");
const ctx = { span };
try {
const instances = await this.workspaceDb.findInstancesByPhaseAndRegion("preparing", region);
const instances = (
await Promise.all([
this.workspaceDb.findInstancesByPhaseAndRegion("preparing", region),
this.workspaceDb.findInstancesByPhaseAndRegion("building", region),
])
).flat();

span.setTag("preparingUpdateEmulatorRun.nrOfInstances", instances.length);
for (const instance of instances) {
const hash = hasher(instance);
Expand Down

0 comments on commit 35e2178

Please sign in to comment.