Skip to content

Commit

Permalink
feat: Added JS executor backend
Browse files Browse the repository at this point in the history
  • Loading branch information
beneboy committed Oct 8, 2019
1 parent 8e09e96 commit 93bcd81
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 15 deletions.
41 changes: 32 additions & 9 deletions src/backends.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as childProcess from "child_process"
import {getLogger} from '@stencila/logga'
import * as childProcess from 'child_process'
import { getLogger } from '@stencila/logga'
const lps = require('length-prefixed-stream')
const { spawn } = require('child_process')
const log = getLogger('engine:backends')
Expand All @@ -10,7 +10,7 @@ export interface ExecutorBackend {
execute(o: any): Promise<any>
}

export class StencilaPythonBackend implements ExecutorBackend {
abstract class StdioBackend implements ExecutorBackend {
private process?: childProcess.ChildProcess

private stdin: any
Expand All @@ -19,9 +19,10 @@ export class StencilaPythonBackend implements ExecutorBackend {

private executionRequestCount: number = 0

setup(): void {
this.process = spawn('python3', ['-m', 'stencila.schema', 'listen'])
if (!this.process) throw new Error('Spawning python3 failed')
protected abstract spawn(): childProcess.ChildProcess

public setup(): void {
this.process = this.spawn()
if (
this.process.stdout === null ||
this.process.stdin === null ||
Expand All @@ -42,15 +43,15 @@ export class StencilaPythonBackend implements ExecutorBackend {
this.stdin.pipe(this.process.stdin)
}

receive(json: Buffer, raw: boolean = false) {
private receive(json: Buffer, raw: boolean = false) {
const response = JSON.parse(json.toString())
const resolve = this.executionRequests[response.id]
resolve(response.body)
delete this.executionRequests[response.id]
}

async execute(o: any): Promise<any> {
if (!this.process) {
public async execute(o: any): Promise<any> {
if (this.process === undefined) {
throw new Error('Can not execute before setup')
}

Expand All @@ -72,3 +73,25 @@ export class StencilaPythonBackend implements ExecutorBackend {
return promise
}
}

export class StencilaPythonBackend extends StdioBackend {
protected spawn() {
return spawn('python3', ['-m', 'stencila.schema', 'listen'])
}
}

export class StencilaJsBackend extends StdioBackend {
protected spawn() {
return spawn(
'npx',
[
'ts-node',
'/Users/ben/Documents/stencila/schema/ts/interpreter',
'listen'
],
{
cwd: '/Users/ben/Documents/stencila/schema'
}
)
}
}
18 changes: 12 additions & 6 deletions src/executa.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import { getLogger } from '@stencila/logga'
import { ExecutorBackend, StencilaPythonBackend } from './backends'
import {
ExecutorBackend,
StencilaJsBackend,
StencilaPythonBackend
} from './backends'

const log = getLogger('engine:serve')

export default class Executa {
backends: { [key: string]: ExecutorBackend } = {}
private backends: { [key: string]: ExecutorBackend } = {}

getBackend(name: string): ExecutorBackend {
private getBackend(name: string): ExecutorBackend {
if (this.backends[name] === undefined) {
switch (name) {
case 'python':
this.backends[name] = new StencilaPythonBackend()
break
case 'javascript':
this.backends[name] = new StencilaJsBackend()
break
default:
throw new Error(`Unknown backend '${name}'`)
}
Expand All @@ -21,9 +28,8 @@ export default class Executa {
return this.backends[name]
}

async execute(code: any): Promise<any> {
public async execute(code: any): Promise<any> {
const backend = this.getBackend(code.programmingLanguage)

return await backend.execute(code)
return backend.execute(code)
}
}

0 comments on commit 93bcd81

Please sign in to comment.