@@ -2,7 +2,6 @@ import * as vscode from 'vscode';
2
2
import net = require( 'net' ) ;
3
3
import { spawn , ChildProcess } from 'child_process' ;
4
4
import { dirname } from 'path' ;
5
- import getPort = require( 'get-port' ) ;
6
5
import * as fs from 'fs' ;
7
6
8
7
interface REvalOutput {
@@ -12,13 +11,23 @@ interface REvalOutput {
12
11
13
12
class RKernel {
14
13
private kernelScript : string ;
14
+ private doc : vscode . NotebookDocument ;
15
15
private cwd : string ;
16
16
private process : ChildProcess ;
17
17
private port : number ;
18
+ private socket : net . Socket ;
18
19
19
20
constructor ( kernelScript : string , doc : vscode . NotebookDocument ) {
20
21
this . kernelScript = kernelScript ;
21
22
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
+ }
22
31
}
23
32
24
33
public async start ( ) {
@@ -29,21 +38,38 @@ class RKernel {
29
38
const env = Object . create ( process . env ) ;
30
39
env . LANG = 'en_US.UTF-8' ;
31
40
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 ( ) ;
42
53
} ) ;
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 ;
45
72
} ) ;
46
- this . process = childProcess ;
47
73
48
74
return new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ;
49
75
}
@@ -61,6 +87,13 @@ class RKernel {
61
87
}
62
88
63
89
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
+ }
64
97
if ( this . process ) {
65
98
const client = net . createConnection ( { host : '127.0.0.1' , port : this . port } , ( ) => {
66
99
console . log ( `uri: ${ cell . uri } , connect` ) ;
0 commit comments