Skip to content
Snippets Groups Projects
Commit 459a4a90 authored by Chris Hines's avatar Chris Hines
Browse files

fix bugs where the UI wasn't updating as the job connected and add a message...

fix bugs where the UI wasn't updating as the job connected and add a message if the popup window is blocked
parent d108337a
No related branches found
No related tags found
1 merge request!3Master
Pipeline #6918 passed
<mat-card> <mat-card>
<mat-card-title>{{ jobdata.name }}</mat-card-title> <mat-card-title>{{ jobdata.name }}</mat-card-title>
<div *ngIf="(jobdata.connectionState === undefined || jobdata.connectionState == 0)"> <div *ngIf="jobdata.connectionState == 0">
<div gdAreas="name name name name| <div gdAreas="name name name name|
status resources space buttons" status resources space buttons"
gdColumns="20% 60% auto 20%"> gdColumns="20% 60% auto 20%">
......
...@@ -19,6 +19,7 @@ export class JobComponent implements OnInit { ...@@ -19,6 +19,7 @@ export class JobComponent implements OnInit {
constructor(private tesService: TesService, private strudelAppsService: StrudelappsService) { constructor(private tesService: TesService, private strudelAppsService: StrudelappsService) {
} }
ngOnInit() { ngOnInit() {
......
...@@ -41,11 +41,17 @@ ...@@ -41,11 +41,17 @@
Advanced Options Advanced Options
</mat-expansion-panel-header> </mat-expansion-panel-header>
Select an API server Select an API server
<mat-select (selectionChange)="tesService.apiserver.next($event.value)" [value]="tesService.apiserver|async"> <!--(selectionChange)="tesService.setApiServer($event.value)" [compareWith]="tesService.compareServers"-->
<mat-select [ngModel]="selectedApiServer" (selectionChange)="tesService.setApiServer($event.value)">
<mat-option *ngFor="let apis of tesService.apiservers|async" [value]="apis"> <mat-option *ngFor="let apis of tesService.apiservers|async" [value]="apis">
{{ apis.name }} {{ apis.name }}
</mat-option> </mat-option>
</mat-select> </mat-select>
<!--<mat-select [ngModel]="tesService.apiserver | async" (ngModelChange)="tesService.setApiServer($event)">
<mat-option *ngFor="let apis of tesService.apiservers|async" [value]="apis">
{{ apis.name }}
</mat-option>
</mat-select>-->
</mat-expansion-panel> </mat-expansion-panel>
</mat-accordion> </mat-accordion>
</mat-sidenav> </mat-sidenav>
......
...@@ -41,6 +41,7 @@ export class LauncherComponent implements OnInit { ...@@ -41,6 +41,7 @@ export class LauncherComponent implements OnInit {
public sshauthzservers: SshAuthzServer[]; public sshauthzservers: SshAuthzServer[];
private launchwindow: any; private launchwindow: any;
private launchwindowWatcher: any; private launchwindowWatcher: any;
public selectedApiServer: any;
constructor( public dialog: MatDialog, constructor( public dialog: MatDialog,
public tesService: TesService, public tesService: TesService,
...@@ -49,6 +50,7 @@ export class LauncherComponent implements OnInit { ...@@ -49,6 +50,7 @@ export class LauncherComponent implements OnInit {
) { ) {
this.authService.sshAuthzServers.subscribe(o => {this.sshauthzservers = o}); this.authService.sshAuthzServers.subscribe(o => {this.sshauthzservers = o});
this.identitySubject = new BehaviorSubject(undefined); this.identitySubject = new BehaviorSubject(undefined);
this.tesService.apiserver.subscribe((s) => this.selectedApiServer = s);
} }
ngOnInit() { ngOnInit() {
...@@ -56,6 +58,7 @@ export class LauncherComponent implements OnInit { ...@@ -56,6 +58,7 @@ export class LauncherComponent implements OnInit {
setTimeout( () => this.authService.updateAgentContents() ) setTimeout( () => this.authService.updateAgentContents() )
} }
//updateIdentities(identities) { //updateIdentities(identities) {
// this.identities = identities; // this.identities = identities;
// console.log(this.identities); // console.log(this.identities);
......
...@@ -32,8 +32,10 @@ Its also responsible for querying a compute site for running jobs */ ...@@ -32,8 +32,10 @@ Its also responsible for querying a compute site for running jobs */
providedIn: 'root', providedIn: 'root',
}) })
export class TesService { export class TesService {
public Base=environment.tesurl; public Base: string;
private twsproxy = environment.twsurl; //public Base=environment.tesurl;
//private twsproxy = environment.twsurl;
private twsproxy: string;
// public Base='http://localhost:5000'; // public Base='http://localhost:5000';
public statusMsg: BehaviorSubject<any>; public statusMsg: BehaviorSubject<any>;
public jobs: any[]; public jobs: any[];
...@@ -58,9 +60,8 @@ public apiservers: BehaviorSubject<APIServer[]>; ...@@ -58,9 +60,8 @@ public apiservers: BehaviorSubject<APIServer[]>;
this.busy = new BehaviorSubject<boolean>(false); this.busy = new BehaviorSubject<boolean>(false);
// this.joblist = new BehaviorSubject<{[id: string]: Job[]}>({}); // this.joblist = new BehaviorSubject<{[id: string]: Job[]}>({});
this.joblist = new BehaviorSubject<Job[]>([]); this.joblist = new BehaviorSubject<Job[]>([]);
this.apiserver = new BehaviorSubject<APIServer>(undefined); this.apiserver = new BehaviorSubject<APIServer>(null);
this.apiservers = new BehaviorSubject<APIServer[]>([]); this.apiservers = new BehaviorSubject<APIServer[]>([]);
this.apiserver.subscribe((r)=>this.onApiServerChange(r));
this.timerSubscription = null; this.timerSubscription = null;
this.appwindowWatcher = null; this.appwindowWatcher = null;
...@@ -73,14 +74,56 @@ public setStatusMsg(statusMsg: BehaviorSubject<any>) { ...@@ -73,14 +74,56 @@ public setStatusMsg(statusMsg: BehaviorSubject<any>) {
this.statusMsg = statusMsg; this.statusMsg = statusMsg;
} }
private onApiServerChange(r) { public compareServer(a: APIServer, b: APIServer) {
if (a.name == b.name) {
return true;
}
return false;
}
private loadLastApiServer() {
var lastserver: APIServer;
try {
console.log('loading api server from local storage');
lastserver = JSON.parse(localStorage.getItem('apiserver'));
} catch {
lastserver = undefined;
}
// If we got a value for the last server used, we need to search the list of available servers for a match
if (lastserver != undefined) {
for (let s of this.apiservers.value) {
if (lastserver.name == s.name) {
this.apiserver.next(s);
}
}
}
// If we didn't get a match, we'll just pick the first available server
if (this.apiserver.value == null) {
if (this.apiservers.value.length > 0) {
this.apiserver.next(this.apiservers.value[0]);
} else {
// If there are NO available backed servers ... well we shouldn't get here.
// In the future if we start detecting backends as down for maintainnce it might happen
this.statusMsg.next("There was an error selecting a backend API server. Please try reloading");
return;
}
}
this.Base = this.apiserver.value.tes; this.Base = this.apiserver.value.tes;
this.twsproxy = this.apiserver.value.tws; this.twsproxy = this.apiserver.value.tws;
console.log('load succeeded');
}
private saveLastApiServer(s: APIServer) {
console.log('saving api server value to local storage')
localStorage.setItem('apiserver', JSON.stringify(s));
} }
setApiServer(server: APIServer) { setApiServer(server: APIServer) {
console.log('calling setAPIServer'); console.log('calling setAPIServer');
this.apiserver.next(server); this.apiserver.next(server);
console.log(this.apiserver);
this.Base = this.apiserver.value.tes;
this.twsproxy = this.apiserver.value.tws;
this.saveLastApiServer(this.apiserver.value)
} }
getAPIServers() { getAPIServers() {
...@@ -92,7 +135,7 @@ private onApiServerChange(r) { ...@@ -92,7 +135,7 @@ private onApiServerChange(r) {
private updateAPIServers(resp) { private updateAPIServers(resp) {
this.apiservers.next(<APIServer[]>resp); this.apiservers.next(<APIServer[]>resp);
this.apiserver.next(this.apiservers.value[0]); this.loadLastApiServer();
} }
...@@ -110,17 +153,52 @@ private onApiServerChange(r) { ...@@ -110,17 +153,52 @@ private onApiServerChange(r) {
return params.toString(); return params.toString();
} }
updateJoblist(resp, identity: Identity) { updateJoblist(resp, identity: Identity) {
let joblist = <Job[]>resp; // resp contains a javascript represnetiation of a list of jobs
let alljobs = this.joblist.value; // We want to update the joblist BUT we don't want to create new Job objects
let i = 0; // instead we want to reuse existing job objects removing any which are no longer valid
for (let j of joblist) { // and adding any new ones. We also want the list sorted from largest jobid to smallest (oldest job)
j.app = this.strudelappsService.getApp(j.name,identity.site.appCatalog.value); // The sort is lexographic since sometimes jobids are a string rather than a number
j.identity = identity;
var joblist: Job[] = []
var jobquery: Job[] = <Job[]>resp;
var lastjoblist: Job[] = this.joblist.value;
var qjobids: any[] = [];
var jobids: any[] = [];
var j: Job
for (j of jobquery) {
qjobids.push(j.jobid);
}
for (j of lastjoblist) {
if (qjobids.indexOf(j.jobid) != -1) {
if (jobids.indexOf(j.jobid) == -1) {
joblist.push(j);
jobids.push(j.jobid);
}
}
}
for (j of jobquery) {
if (jobids.indexOf(j.jobid) == -1) {
joblist.push(j);
jobids.push(j.jobid);
}
}
for (j of joblist) {
if (j.app === undefined) {
j.app = this.strudelappsService.getApp(j.name,identity.site.appCatalog.value);
}
if (j.identity == undefined) {
j.identity = identity;
}
if (j.connectionState == undefined) {
j.connectionState = 0;
}
} }
joblist = joblist.sort((a,b) => (a.jobid < b.jobid)? 1:-1);
this.joblist.next(joblist) this.joblist.next(joblist)
// alljobs[identity.repr()] = joblist;
// this.joblist.next(alljobs);
} }
private getBatchInterfaceError(error: any) { private getBatchInterfaceError(error: any) {
...@@ -258,12 +336,17 @@ private onApiServerChange(r) { ...@@ -258,12 +336,17 @@ private onApiServerChange(r) {
let batchhost = job.batch_host; let batchhost = job.batch_host;
let params = new URLSearchParams; let params = new URLSearchParams;
let headers = new HttpHeaders(); let headers = new HttpHeaders();
console.log('setting Connectionstate 2');
job.connectionState = 2; job.connectionState = 2;
// let sleepDuration = 20;
//var now = new Date().getTime();
//while(new Date().getTime() < now + sleepDuration){ /* do nothing */ }
let options = { headers: headers, withCredentials: true}; let options = { headers: headers, withCredentials: true};
params.set('cmd',JSON.stringify(job.app.paramscmd)); params.set('cmd',JSON.stringify(job.app.paramscmd));
let paramstr = params.toString(); let paramstr = params.toString();
this.http.post<string>(this.Base+'/createtunnel/'+username+'/'+loginhost+'/'+batchhost+'?'+paramstr, job.appinst, options) this.http.post<string>(this.Base+'/createtunnel/'+username+'/'+loginhost+'/'+batchhost+'?'+paramstr, job.appinst, options)
// .pipe(catchError(this.handleError))
.subscribe(() => { this.getAppUrl(job) } ) .subscribe(() => { this.getAppUrl(job) } )
} }
...@@ -291,6 +374,14 @@ private onApiServerChange(r) { ...@@ -291,6 +374,14 @@ private onApiServerChange(r) {
console.log('window loc is ',windowloc); console.log('window loc is ',windowloc);
// let windowloc = this.router.config // let windowloc = this.router.config
this.appwindow = window.open(windowloc); this.appwindow = window.open(windowloc);
console.log('check if the appwindow is valid',this.appwindow);
if (this.appwindow == null) {
this.statusMsg.next('It looks like a window failed to open. Please check your popup blocker settings (Strudel 2 needs to be able to open a window to your application');
return;
}
if (this.appwindow.closed) {
console.log('appwindow failed to open');
}
if (!(this.appwindowWatcher === null)) { if (!(this.appwindowWatcher === null)) {
this.appwindowWatcher.unsubscribe() this.appwindowWatcher.unsubscribe()
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment