1
0
mirror of https://github.com/sasjs/server.git synced 2026-01-05 22:00:05 +00:00

fix: session refactoring with Saad & Allan

This commit is contained in:
Allan Bowe
2021-11-13 14:31:09 +00:00
parent a4ac5dc280
commit cbe07b4abb
7 changed files with 98 additions and 34 deletions

View File

@@ -1,4 +1,7 @@
import { Session } from '../../types'
import { configuration } from '../../../package.json'
import { promisify } from 'util'
import { execFile } from 'child_process'
import { getTmpSessionsFolderPath, generateUniqueFileName } from '../../utils'
import {
deleteFolder,
@@ -9,6 +12,9 @@ import {
} from '@sasjs/utils'
import path from 'path'
import { ExecutionController } from './Execution'
import { date } from 'joi'
const execFilePromise = promisify(execFile)
export class SessionController {
private sessions: Session[] = []
@@ -34,7 +40,8 @@ export class SessionController {
const sessionId = generateUniqueFileName(generateTimestamp())
const sessionFolder = path.join(getTmpSessionsFolderPath(), sessionId)
const autoExecContent = `data _null_;
const autoExecContent = `
data _null_;
/* remove the dummy SYSIN */
length fname $8;
rc=filename(fname,getoption('SYSIN') );
@@ -45,12 +52,14 @@ export class SessionController {
do until ( fileexist(getoption('SYSIN')) or slept>(60*15) );
slept=slept+sleep(0.01,1);
end;
stop;
run;
EOL`
`
// the autoexec file is executed on SAS startup
const autoExec = path.join(sessionFolder, 'autoexec.sas')
await createFile(autoExec, autoExecContent)
// a dummy SYSIN code.sas file is necessary to start SAS
await createFile(path.join(sessionFolder, 'code.sas'), '')
const creationTimeStamp = sessionId.split('-').pop() as string
@@ -65,17 +74,49 @@ export class SessionController {
1000
).toString(),
path: sessionFolder,
inUse: false
inUse: false,
completed: false
}
// we do not want to leave sessions running forever
// we clean them up after a predefined period, if unused
this.scheduleSessionDestroy(session)
this.executionController
.execute('', undefined, autoExec, session)
.catch(() => {})
// create empty code.sas as SAS will not start without a SYSIN
const codePath = path.join(session.path, 'code.sas')
await createFile(codePath, '')
// this.executionController
// .execute('', undefined, autoExec, session)
// .catch((err) => {console.log(err)})
// trigger SAS but don't wait for completion - we need to
// update the session array to say that it is currently running
// however we also need a promise so that we can update the
// session array to say that it has (eventually) finished.
const sasLoc = process.sasLoc ?? configuration.sasPath
execFilePromise(sasLoc, [
'-SYSIN',
codePath,
'-LOG',
path.join(session.path, 'log.log'),
'-WORK',
session.path,
'-AUTOEXEC',
path.join(session.path, 'autoexec.sas'),
process.platform === 'win32' ? '-nosplash' : ''
]).then(() => {
session.completed=true
console.log('session completed', session)
}).catch((err) => {})
// we have a triggered session - add to array
this.sessions.push(session)
// SAS has been triggered but we can't use it until
// the autoexec deletes the code.sas file
await this.waitForSession(session)
return session
@@ -85,8 +126,6 @@ export class SessionController {
if (await fileExists(path.join(session.path, 'code.sas'))) {
while (await fileExists(path.join(session.path, 'code.sas'))) {}
await deleteFile(path.join(session.path, 'log.log'))
session.ready = true
return Promise.resolve(session)
@@ -98,8 +137,10 @@ export class SessionController {
}
public async deleteSession(session: Session) {
// remove the temporary files, to avoid buildup
await deleteFolder(session.path)
// remove the session from the session array
if (session.ready) {
this.sessions = this.sessions.filter(
(sess: Session) => sess.id !== session.id