@@ -54,6 +54,12 @@ export interface RestfulClientOptions {
5454 host ?: string ;
5555 username ?: string ;
5656 password ?: string ;
57+ timeout ?: number ;
58+ }
59+
60+ const DEFAULT_OPTIONS : Required < Pick < RestfulClientOptions , 'host' | 'timeout' > > = {
61+ host : 'http://localhost:8088' ,
62+ timeout : 25000 ,
5763}
5864
5965export class RestfulClient {
@@ -67,10 +73,24 @@ export class RestfulClient {
6773 this . connect ( ) ;
6874 }
6975
76+ /**
77+ * The connect method will create a promise "startSession" method, not really to connect http2 immediately.
78+ * To let users establish a "startSession" promise request only when they need to query or exec a statement.
79+ */
7080 public connect ( ) {
7181 this . startSession = ( ) =>
7282 new Promise ( ( resolve , reject ) => {
73- this . client = http2 . connect ( this . options . host || 'http://localhost:8088' ) ;
83+ this . client = http2 . connect ( this . options . host || DEFAULT_OPTIONS . host , {
84+ timeout : this . options . timeout || DEFAULT_OPTIONS . timeout ,
85+ } ) ;
86+
87+ this . client . setTimeout ( this . options . timeout || DEFAULT_OPTIONS . timeout , ( ) => {
88+ if ( this . connected === false ) {
89+ const timeoutError = new Error ( "Connection timeout." ) ;
90+ reject ( timeoutError ) ;
91+ this . client ?. destroy ( timeoutError ) ;
92+ }
93+ } ) ;
7494
7595 this . client . on ( 'connect' , ( ) => {
7696 this . connected = true ;
@@ -83,7 +103,7 @@ export class RestfulClient {
83103 } ) ;
84104 }
85105
86- public close ( ) : Promise < void > {
106+ public closeSession ( ) : Promise < void > {
87107 return new Promise ( ( resolve , reject ) => {
88108 if ( this . client ) {
89109 ! this . client . destroyed && this . client . destroy ( ) ;
@@ -116,6 +136,11 @@ export class RestfulClient {
116136 return isRunning ;
117137 }
118138
139+ /**
140+ * According to ksqldb restful API: https://docs.ksqldb.io/en/latest/developer-guide/ksqldb-rest-api/query-endpoint
141+ * To run a SELECT statement and stream back the results.
142+ * SELECT statement: https://docs.ksqldb.io/en/latest/developer-guide/ksqldb-reference/select-pull-query
143+ */
119144 public async query ( {
120145 query,
121146 query_params = { } ,
@@ -131,6 +156,11 @@ export class RestfulClient {
131156 return res ;
132157 }
133158
159+ /**
160+ * According to ksqldb restful API: https://docs.ksqldb.io/en/latest/developer-guide/ksqldb-rest-api/ksql-endpoint
161+ * All statements, except those starting with SELECT and PRINT, can be run on this exec method.
162+ * To run SELECT and PRINT statements use the "query" method instead.
163+ */
134164 public async exec ( {
135165 query,
136166 query_params = { } ,
@@ -153,6 +183,8 @@ export class RestfulClient {
153183 const ksql = query . replace ( / \$ ( \d + ) / g, ( _ , index ) => {
154184 const valueIndex = parseInt ( index ) - 1 ;
155185 const paramValue = values [ valueIndex ] ;
186+ // Because the ksqldb queries are expressed using a strict subset of ANSI SQL.
187+ // It didn't support the string auto conversion, so we need to add the single quote for string value.
156188 return typeof paramValue === 'string' ? `'${ paramValue } '` : paramValue ;
157189 } ) ;
158190
@@ -203,12 +235,12 @@ export class RestfulClient {
203235 } else {
204236 reject ( responseData ) ;
205237 }
206- this . close ( ) ;
238+ this . closeSession ( ) ;
207239 } ) ;
208240
209241 req . on ( 'error' , ( error ) => {
210242 reject ( error ) ;
211- this . close ( ) ;
243+ this . closeSession ( ) ;
212244 } ) ;
213245
214246 buffer && req . write ( buffer ) ;
0 commit comments