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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user