Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions src/r-bridge/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import semver from 'semver/preload'
import { getPlatform } from '../util/os'
import fs from 'fs'
import { getConfig } from '../config'
import type { AsyncOrSync } from 'ts-essentials'

export type OutputStreamSelector = 'stdout' | 'stderr' | 'both';

Expand All @@ -21,6 +22,10 @@ export interface CollectorTimeout extends MergeableRecord {
* if true, the timeout will reset whenever we receive new data
*/
resetOnNewData: boolean
/**
* invoked when the timeout is reached. If not set, the promise will be rejected with an error.
*/
onTimeout?: (resolve: (value: AsyncOrSync<string[]>) => void, reject: (value: AsyncOrSync<string[]>) => void, partialResult: string[]) => void
}

interface CollectorUntil extends MergeableRecord {
Expand Down Expand Up @@ -162,10 +167,21 @@ export class RShell {
return this.versionCache
}
// retrieve raw version:
const result = await this.sendCommandWithOutput(`cat(paste0(R.version$major,".",R.version$minor), ${ts2r(this.options.eol)})`)
const result = await this.sendCommandWithOutput(`cat(paste0(R.version$major,".",R.version$minor), ${ts2r(this.options.eol)})`, {
timeout: {
ms: 1000,
resetOnNewData: false,
// just resolve on timeout and handle the empty array case below
onTimeout: resolve => resolve([])
}
})
this.log.trace(`raw version: ${JSON.stringify(result)}`)
this.versionCache = semver.coerce(result[0])
return result.length === 1 ? this.versionCache : null
if(result.length === 1) {
this.versionCache = semver.coerce(result[0])
return this.versionCache
} else {
return null
}
}

public injectLibPaths(...paths: string[]): void {
Expand Down Expand Up @@ -337,7 +353,11 @@ class RShellSession {

return await new Promise<string[]>((resolve, reject) => {
const makeTimer = (): NodeJS.Timeout => setTimeout(() => {
reject(new Error(`timeout of ${timeout.ms}ms reached (${JSON.stringify(result)})`))
if(timeout.onTimeout) {
timeout.onTimeout(resolve, reject, result)
} else {
reject(new Error(`timeout of ${timeout.ms}ms reached (${JSON.stringify(result)})`))
}
}, timeout.ms)
this.collectionTimeout = makeTimer()

Expand Down