@@ -2,7 +2,6 @@ import * as vscode from 'vscode';
22import net = require( 'net' ) ;
33import { spawn , ChildProcess } from 'child_process' ;
44import { dirname } from 'path' ;
5- import getPort = require( 'get-port' ) ;
65import * as fs from 'fs' ;
76
87interface REvalOutput {
@@ -12,13 +11,23 @@ interface REvalOutput {
1211
1312class RKernel {
1413 private kernelScript : string ;
14+ private doc : vscode . NotebookDocument ;
1515 private cwd : string ;
1616 private process : ChildProcess ;
1717 private port : number ;
18+ private socket : net . Socket ;
1819
1920 constructor ( kernelScript : string , doc : vscode . NotebookDocument ) {
2021 this . kernelScript = kernelScript ;
2122 this . cwd = dirname ( doc . uri . fsPath ) ;
23+ this . doc = doc ;
24+ }
25+
26+ private request ( obj : any ) {
27+ if ( this . socket ) {
28+ const json = JSON . stringify ( obj ) ;
29+ this . socket . write ( `Content-Length: ${ json . length } \n${ json } \n` ) ;
30+ }
2231 }
2332
2433 public async start ( ) {
@@ -29,21 +38,38 @@ class RKernel {
2938 const env = Object . create ( process . env ) ;
3039 env . LANG = 'en_US.UTF-8' ;
3140
32- this . port = await getPort ( ) ;
33- const childProcess = spawn ( 'R' , [ '--quiet' , '--slave' , '-f' , this . kernelScript , '--args' , `port=${ this . port } ` ] ,
34- { cwd : this . cwd , env : env } ) ;
35- childProcess . stderr . on ( 'data' , ( chunk : Buffer ) => {
36- const str = chunk . toString ( ) ;
37- console . log ( `R stderr (${ childProcess . pid } ): ${ str } ` ) ;
38- } ) ;
39- childProcess . stdout . on ( 'data' , ( chunk : Buffer ) => {
40- const str = chunk . toString ( ) ;
41- console . log ( `R stdout (${ childProcess . pid } ): ${ str } ` ) ;
41+ const server = net . createServer ( socket => {
42+ console . log ( 'socket started' ) ;
43+ this . socket = socket ;
44+ socket . on ( 'data' , ( chunk : Buffer ) => {
45+ const str = chunk . toString ( ) ;
46+ console . log ( `socket (${ socket . localAddress } :${ socket . localPort } ): ${ str } ` ) ;
47+ } ) ;
48+ socket . on ( 'end' , ( ) => {
49+ console . log ( 'socket disconnected' ) ;
50+ this . socket = undefined ;
51+ } ) ;
52+ server . close ( ) ;
4253 } ) ;
43- childProcess . on ( 'exit' , ( code , signal ) => {
44- console . log ( `R exited with code ${ code } ` ) ;
54+
55+ server . listen ( 0 , '127.0.0.1' , ( ) => {
56+ this . port = ( server . address ( ) as net . AddressInfo ) . port ;
57+ const childProcess = spawn ( 'R' , [ '--quiet' , '--slave' , '-f' , this . kernelScript , '--args' , `port=${ this . port } ` ] ,
58+ { cwd : this . cwd , env : env } ) ;
59+ childProcess . stderr . on ( 'data' , ( chunk : Buffer ) => {
60+ const str = chunk . toString ( ) ;
61+ console . log ( `R stderr (${ childProcess . pid } ): ${ str } ` ) ;
62+ } ) ;
63+ childProcess . stdout . on ( 'data' , ( chunk : Buffer ) => {
64+ const str = chunk . toString ( ) ;
65+ console . log ( `R stdout (${ childProcess . pid } ): ${ str } ` ) ;
66+ } ) ;
67+ childProcess . on ( 'exit' , ( code , signal ) => {
68+ console . log ( `R exited with code ${ code } ` ) ;
69+ } ) ;
70+ this . process = childProcess ;
71+ return childProcess ;
4572 } ) ;
46- this . process = childProcess ;
4773
4874 return new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ;
4975 }
@@ -61,6 +87,13 @@ class RKernel {
6187 }
6288
6389 public async eval ( cell : vscode . NotebookCell ) : Promise < REvalOutput > {
90+ if ( this . socket ) {
91+ this . request ( {
92+ uri : cell . uri ,
93+ time : Date . now ( ) ,
94+ expr : cell . document . getText ( ) ,
95+ } ) ;
96+ }
6497 if ( this . process ) {
6598 const client = net . createConnection ( { host : '127.0.0.1' , port : this . port } , ( ) => {
6699 console . log ( `uri: ${ cell . uri } , connect` ) ;
0 commit comments