Skip to content

Commit

Permalink
fix: failing session page needed advanced terminal too
Browse files Browse the repository at this point in the history
  • Loading branch information
wufe committed Jan 18, 2024
1 parent b657c13 commit 28d6f1b
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 29 deletions.
4 changes: 1 addition & 3 deletions client/common/api/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import { SessionStatus, SessionKillReason } from '../state/models/session-model-
import Axios from 'axios';
import { buildRequest } from './common';

export interface IAPISession extends Omit<ISession, 'logs'> {
logs: ISessionLog[];
}
export interface IAPISession extends ISession {}

export interface IAPISessionLogsAndStatus {
logs: ISessionLog[];
Expand Down
6 changes: 5 additions & 1 deletion client/common/state/models/failures-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { APIPayload, APIRequestResult } from "@polo/common/api/common";
import { values } from "mobx";
import { flow, getParent, hasParent, types } from "mobx-state-tree";
import { IApp, SessionSubscriptionEventType } from ".";
import { ISession, ISessionLog, SessionModel } from "./session-model";
import { ISession, ISessionLog, SessionModel, castAPISessionToSessionModel } from "./session-model";

export enum FailureStatus {
ACK = 'acknowledged',
Expand All @@ -19,6 +19,7 @@ export type TFailuresDictionary = {
};

export const FailuresModel = types.model({
currentSession: types.maybeNull(SessionModel),
acknowledged : types.map(SessionModel),
unacknowledged: types.map(SessionModel),
})
Expand Down Expand Up @@ -49,6 +50,9 @@ export const FailuresModel = types.model({
const retrieveFailedSession = flow(function* retrieveFailedSession(uuid: string, markAsSeen = true) {
const request: APIPayload<ISession> = yield retrieveFailedSessionAPI(uuid);
if (markAsSeen) markFailedSessionAsAcknowledged(uuid);
if (request.result === APIRequestResult.SUCCEEDED) {
self.currentSession = castAPISessionToSessionModel(request.payload);
}
return request;
});

Expand Down
2 changes: 1 addition & 1 deletion client/common/state/models/session-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const castAPISessionToSessionModel = (apiSession: IAPISession): ISession
const { logs, ...rest } = apiSession;
const session = rest as ISession;
if (logs) {
session.logs = logs.reduce<{ [k: string]: ISessionLog }>((acc, log) => {
session.logs = Array.from(logs.values()).reduce<{ [k: string]: ISessionLog }>((acc, log) => {
acc[log.uuid] = log;
return acc;
}, {}) as any;
Expand Down
9 changes: 9 additions & 0 deletions client/manager/src/components/session/failing-session.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@import "@polo/common/styles/index";

.xterm-rows {
@apply m-3;
}

.xterm-cursor {
display: none !important;
}
38 changes: 23 additions & 15 deletions client/manager/src/components/session/failing-session.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { APIRequestResult } from '@polo/common/api/common';
import { IApp } from '@polo/common/state/models/app-model';
import { ISession, ISessionLog } from '@polo/common/state/models/session-model';
import { ISession, ISessionLog, castAPISessionToSessionModel } from '@polo/common/state/models/session-model';
import dayjs from 'dayjs';
import { values } from 'mobx';
import { observer } from 'mobx-react-lite';
Expand All @@ -9,6 +9,10 @@ import { useHistory } from 'react-router-dom';
import { CommitMessage } from '../shared/commit-message';
import { SessionLogs } from './session-logs';
import { useSessionRetrieval } from './session-retrieval-hook';
import { SessionTerminalContainer } from './session-terminal-container';
import '@polo/manager/src/components/session/failing-session.scss';

const useAdvancedTerminal = window.configuration.advancedTerminalOutput;

type TProps = {
app: IApp;
Expand All @@ -32,30 +36,34 @@ export const FailingSession = observer((props: TProps) => {
props.app.failures.retrieveFailedSession(props.uuid),
props.app.failures.retrieveFailedSessionLogs(props.uuid)
])
.then(([sessionResponse, logsResponse]) => {
if (sessionResponse.result === APIRequestResult.FAILED) {
return history.push(`/_polo_`);
}
setSession(sessionResponse.payload);
if (logsResponse.result === APIRequestResult.SUCCEEDED)
setLogs(logsResponse.payload);
})
.then(([sessionResponse, logsResponse]) => {
if (sessionResponse.result === APIRequestResult.FAILED) {
return history.push(`/_polo_`);
}
const session = castAPISessionToSessionModel(sessionResponse.payload);
setSession(session);
if (logsResponse.result === APIRequestResult.SUCCEEDED)
setLogs(logsResponse.payload);
})
}, [props.uuid]);

if (!session) return null;
if (!props.app.failures.currentSession) return null;

return <div className="
mx-auto w-full max-w-6xl flex flex-col min-w-0 min-h-0 flex-1 pt-3 font-quicksand" style={{ maxHeight: 'calc(100vh - 120px)' }}>
<div className="main-gradient-faded absolute left-0 right-0 top-0 pointer-events-none" style={{ bottom: `${overlayBottom}%`, zIndex: 1 }}></div>
<h1 className="text-4xl px-2 lg:px-0 mb-3 font-quicksand font-light text-nord1 dark:text-nord5 z-10">Failing session</h1>
<h1 className="text-4xl px-2 lg:px-0 mb-3 font-quicksand font-light text-nord1 dark:text-nord5 z-10">
Failing session
</h1>
<div className="text-lg text-nord1 dark:text-nord5 mb-4 z-10 border-l pl-3 border-gray-500">
<span>{session.displayName}</span>
<span>{props.app.failures.currentSession.displayName}</span>
</div>
<CommitMessage {...session} maxHeight />
<SessionLogs
<CommitMessage {...props.app.failures.currentSession} maxHeight />
{useAdvancedTerminal && <SessionTerminalContainer app={props.app} session={props.app.failures.currentSession} />}
{!useAdvancedTerminal && <SessionLogs
failed
logs={logs}
onLogsProportionChanged={setOverlayProportions} />
onLogsProportionChanged={setOverlayProportions} />}
</div>
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export const useSessionTerminalRetrieval = (
session: ISession,
container: React.MutableRefObject<HTMLDivElement>,
retrieveFailedSession: (uuid: string) => Promise<APIPayload<ISession>>,
onSessionFail: () => void,
onSessionFail?: () => void,
) => {
const interval = useRef<NodeJS.Timeout | null>(null);
const history = useHistory();
Expand Down Expand Up @@ -105,7 +105,7 @@ export const useSessionTerminalRetrieval = (
const failedSessionRequest = await retrieveFailedSession(session.uuid);
if (failedSessionRequest.result === APIRequestResult.SUCCEEDED) {
redirectToDashboard = false;
onSessionFail();
onSessionFail?.();
}
} catch (e) {
console.error(e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import {useSessionTerminalRetrieval} from '@/components/session/session-retrieval-hook';
import {IApp, ISession} from '@polo/common/state/models';
import {observer} from 'mobx-react-lite';
import { useSessionTerminalRetrieval } from '@/components/session/session-retrieval-hook';
import { IApp, ISession } from '@polo/common/state/models';
import { observer } from 'mobx-react-lite';
import React from 'react';
import 'xterm/css/xterm.css';

type TProps = {
app: IApp;
session: ISession;
onSessionFail: () => void;
onSessionFail?: () => void;
};

export const SessionTerminalContainer = observer((props: TProps) => {
Expand Down
1 change: 0 additions & 1 deletion client/manager/src/components/session/session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { observer } from 'mobx-react-lite';
import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
import { CommitMessage } from '../shared/commit-message';
import 'xterm/css/xterm.css';
import '@polo/manager/src/components/session/session.scss';
import { SessionIntegrationsStatus } from './integrations-status/session-integrations-status';

Expand Down
2 changes: 1 addition & 1 deletion pkg/http/rest/rest-handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ func (h *Handler) getSessionPTY(query *services.QueryService, logger logging.Log
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
uuid := p.ByName("uuid")
tty, _, err := query.GetSessionTTY(uuid)
defer tty.Close()

if err != nil {
logger.Error("Error retrieving session TTY: %s", err)
Expand All @@ -212,6 +211,7 @@ func (h *Handler) getSessionPTY(query *services.QueryService, logger logging.Log
w.Write(c)
return
}
defer tty.Close()

if _, err := tty.Seek(0, io.SeekStart); err != nil {
logger.Error("Error seeking TTY output: %s\n", err)
Expand Down
13 changes: 12 additions & 1 deletion pkg/services/query-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ func (s *QueryService) GetAllAliveSessions() []*models.Session {
return s.sessionStorage.GetAllAliveSessions()
}

// GetSession returns a session by its UUID, undependently from its status
func (s *QueryService) GetSession(uuid string) *models.Session {
var foundSession *models.Session
for _, session := range s.sessionStorage.GetAll() {
if session.UUID == uuid {
foundSession = session
}
}
return foundSession
}

func (s *QueryService) GetAliveSession(uuid string) *models.Session {
var foundSession *models.Session
for _, session := range s.sessionStorage.GetAllAliveSessions() {
Expand Down Expand Up @@ -98,7 +109,7 @@ func (s *QueryService) GetSessionLogsAndStatus(uuid string, lastLogUUID string)
}

func (s *QueryService) GetSessionTTY(uuid string) (utils.TTY, models.SessionStatus, error) {
session := s.GetAliveSession(uuid)
session := s.GetSession(uuid)
if session == nil {
return nil, models.SessionStatusStarting, ErrSessionNotFound
}
Expand Down
11 changes: 11 additions & 0 deletions pkg/storage/session-storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,17 @@ func (s *Session) GetByUUID(uuid string) *models.Session {
return foundSession
}

// GetAll retrieves all sessions
func (s *Session) GetAll() []*models.Session {
s.log.Trace("Getting all alive sessions")
s.RLock()
filteredSessions := make([]*models.Session, 0, len(s.sessions))
sessions := s.sessions
s.RUnlock()
filteredSessions = append(filteredSessions, sessions...)
return filteredSessions
}

// GetAllAliveSessions retrieves a slice of sessions whose status is "alive".
// A session is "alive" if it can or is about to ready for being used
func (s *Session) GetAllAliveSessions() []*models.Session {
Expand Down

0 comments on commit 28d6f1b

Please sign in to comment.