@@ -28,13 +28,13 @@ function! denops#_internal#server#chan#connect(addr, options) abort
2828 endif
2929 let l: retry_threshold = a: options .retry_threshold
3030 let l: retry_interval = a: options .retry_interval
31- let l: previous_exception = ' '
32- for l: i in range ( l: retry_threshold )
31+ let l: i = 1
32+ while v: true
3333 call denops#_internal#echo#debug (printf (
3434 \ ' Connecting to channel `%s` [%d/%d]' ,
3535 \ a: addr ,
36- \ l: i + 1 ,
37- \ l: retry_threshold + 1 ,
36+ \ l: i ,
37+ \ l: retry_threshold ,
3838 \) )
3939 try
4040 call s: connect (a: addr , a: options )
@@ -43,28 +43,45 @@ function! denops#_internal#server#chan#connect(addr, options) abort
4343 call denops#_internal#echo#debug (printf (
4444 \ ' Failed to connect channel `%s` [%d/%d]: %s' ,
4545 \ a: addr ,
46- \ l: i + 1 ,
47- \ l: retry_threshold + 1 ,
46+ \ l: i ,
47+ \ l: retry_threshold ,
4848 \ v: exception ,
4949 \) )
50- let l: previous_exception = v: exception
50+ if l: i >= l: retry_threshold
51+ call denops#_internal#echo#error (printf (
52+ \ ' Failed to connect channel `%s`: %s' ,
53+ \ a: addr ,
54+ \ v: exception ,
55+ \) )
56+ return
57+ endif
5158 endtry
5259 execute printf (' sleep %dm' , l: retry_interval )
53- endfor
54- call denops#_internal#echo#error (printf (
55- \ ' Failed to connect channel `%s`: %s' ,
56- \ a: addr ,
57- \ l: previous_exception ,
58- \) )
60+ endwhile
5961endfunction
6062
61- function ! denops#_internal#server#chan#close () abort
63+ " Args:
64+ " options: {
65+ " timeout: number (default: 0)
66+ " }
67+ function ! denops#_internal#server#chan#close (options ) abort
6268 if s: chan is # v: null
6369 throw ' [denops] Channel does not exist yet'
6470 endif
71+ let l: options = extend ({
72+ \ ' timeout' : 0 ,
73+ \} , a: options )
6574 let s: closed_on_purpose = 1
66- call s: rpcclose (s: chan )
67- let s: chan = v: null
75+ if l: options .timeout == # 0
76+ return s: force_close (l: options )
77+ endif
78+ if l: options .timeout > 0
79+ let s: force_close_delayer = timer_start (
80+ \ l: options .timeout ,
81+ \ { - > s: force_close (l: options ) },
82+ \)
83+ endif
84+ call denops#_internal#server#chan#notify (' invoke' , [' close' , []])
6885endfunction
6986
7087function ! denops#_internal#server#chan#is_connected () abort
@@ -91,36 +108,56 @@ endfunction
91108
92109function ! s: connect (addr, options ) abort
93110 let s: closed_on_purpose = 0
94- let s: chan = s: rpcconnect (a: addr , {
95- \ ' on_close' : { - > s: on_close (a: options ) },
96- \} )
97111 let s: addr = a: addr
98112 let s: options = a: options
113+ let s: chan = s: rpcconnect (a: addr , {
114+ \ ' on_close' : { - > s: on_close () },
115+ \} )
99116 call denops#_internal#echo#debug (printf (' Channel connected (%s)' , a: addr ))
100117 call s: rpcnotify (s: chan , ' void' , [])
101118endfunction
102119
103- function ! s: on_close (options ) abort
120+ function ! s: force_close (options ) abort
121+ let l: chan = s: chan
122+ let s: chan = v: null
123+ call s: clear_force_close_delayer ()
124+ call denops#_internal#echo#warn (printf (
125+ \ ' Channel cannot close gracefully within %d millisec, force close (%s)' ,
126+ \ a: options .timeout ,
127+ \ s: addr ,
128+ \) )
129+ call s: rpcclose (l: chan )
130+ endfunction
131+
132+ function ! s: clear_force_close_delayer () abort
133+ if exists (' s:force_close_delayer' )
134+ call timer_stop (s: force_close_delayer )
135+ unlet s: force_close_delayer
136+ endif
137+ endfunction
138+
139+ function ! s: on_close () abort
104140 let s: chan = v: null
141+ call s: clear_force_close_delayer ()
105142 call denops#_internal#echo#debug (printf (' Channel closed (%s)' , s: addr ))
106143 doautocmd <nomodeline> User DenopsClosed
107- if ! a : options .reconnect_on_close || s: closed_on_purpose || s: exiting
144+ if s: chan isnot # v: null || ! s : options .reconnect_on_close || s: closed_on_purpose || s: exiting
108145 return
109146 endif
110147 " Reconnect
111- if s: reconnect_guard (a: options )
148+ if s: reconnect_guard ()
112149 return
113150 endif
114151 call denops#_internal#echo#warn (' Channel closed. Reconnecting...' )
115152 call timer_start (
116- \ a : options .reconnect_delay,
153+ \ s : options .reconnect_delay,
117154 \ { - > denops#_internal#server#chan#connect (s: addr , s: options ) },
118155 \)
119156endfunction
120157
121- function ! s: reconnect_guard (options ) abort
122- let l: reconnect_threshold = a : options .reconnect_threshold
123- let l: reconnect_interval = a : options .reconnect_interval
158+ function ! s: reconnect_guard () abort
159+ let l: reconnect_threshold = s : options .reconnect_threshold
160+ let l: reconnect_interval = s : options .reconnect_interval
124161 let s: reconnect_count = get (s: , ' reconnect_count' , 0 ) + 1
125162 if s: reconnect_count >= l: reconnect_threshold
126163 call denops#_internal#echo#warn (printf (
0 commit comments