16
16
* job names instead of PIDs
17
17
"""
18
18
import pwd
19
- import os
19
+ import os , asyncio
20
20
21
21
import xml .etree .ElementTree as ET
22
22
@@ -177,53 +177,46 @@ def parse_job_id(self, output):
177
177
def cmd_formatted_for_batch (self ):
178
178
return ' ' .join (self .cmd + self .get_args ())
179
179
180
- @gen .coroutine
181
- def run_command (self , cmd , input = None , env = None ):
182
- proc = Subprocess (cmd , shell = True , env = env , stdin = Subprocess .STREAM , stdout = Subprocess .STREAM ,stderr = Subprocess .STREAM )
183
- inbytes = None
180
+ async def run_command (self , cmd , input = None , env = None ):
181
+ proc = await asyncio .create_subprocess_shell (cmd , env = env ,
182
+ stdin = asyncio .subprocess .PIPE ,
183
+ stdout = asyncio .subprocess .PIPE ,
184
+ stderr = asyncio .subprocess .PIPE )
185
+ inbytes = None
186
+
184
187
if input :
185
- inbytes = input .encode ()
186
- try :
187
- yield proc .stdin .write (inbytes )
188
- except StreamClosedError as exp :
189
- # Apparently harmless
190
- pass
191
- proc .stdin .close ()
192
- out = yield proc .stdout .read_until_close ()
193
- eout = yield proc .stderr .read_until_close ()
194
- proc .stdout .close ()
195
- proc .stderr .close ()
188
+ inbytes = input .encode ()
189
+
190
+ out , eout = await proc .communicate (input = inbytes )
191
+
196
192
eout = eout .decode ().strip ()
197
- try :
198
- err = yield proc .wait_for_exit ()
199
- except CalledProcessError :
200
- self .log .error ("Subprocess returned exitcode %s" % proc .returncode )
193
+
194
+ err = proc .returncode
195
+
196
+ if err != 0 :
197
+ self .log .error ("Subprocess returned exitcode %s" % err )
201
198
self .log .error (eout )
202
199
raise RuntimeError (eout )
203
- if err != 0 :
204
- return err # exit error?
205
200
else :
206
201
out = out .decode ().strip ()
207
202
return out
208
203
209
- @gen .coroutine
210
- def _get_batch_script (self , ** subvars ):
204
+ async def _get_batch_script (self , ** subvars ):
211
205
"""Format batch script from vars"""
212
206
# Colud be overridden by subclasses, but mainly useful for testing
213
207
return format_template (self .batch_script , ** subvars )
214
208
215
- @gen .coroutine
216
- def submit_batch_script (self ):
209
+ async def submit_batch_script (self ):
217
210
subvars = self .get_req_subvars ()
218
211
cmd = self .exec_prefix + ' ' + self .batch_submit_cmd
219
212
cmd = format_template (cmd , ** subvars )
220
213
subvars ['cmd' ] = self .cmd_formatted_for_batch ()
221
214
if hasattr (self , 'user_options' ):
222
215
subvars .update (self .user_options )
223
- script = yield self ._get_batch_script (** subvars )
216
+ script = await self ._get_batch_script (** subvars )
224
217
self .log .info ('Spawner submitting job using ' + cmd )
225
218
self .log .info ('Spawner submitted script:\n ' + script )
226
- out = yield self .run_command (cmd , input = script , env = self .get_env ())
219
+ out = await self .run_command (cmd , input = script , env = self .get_env ())
227
220
try :
228
221
self .log .info ('Job submitted. cmd: ' + cmd + ' output: ' + out )
229
222
self .job_id = self .parse_job_id (out )
@@ -238,8 +231,7 @@ def submit_batch_script(self):
238
231
"and self.job_id as {job_id}."
239
232
).tag (config = True )
240
233
241
- @gen .coroutine
242
- def read_job_state (self ):
234
+ async def read_job_state (self ):
243
235
if self .job_id is None or len (self .job_id ) == 0 :
244
236
# job not running
245
237
self .job_status = ''
@@ -250,7 +242,7 @@ def read_job_state(self):
250
242
cmd = format_template (cmd , ** subvars )
251
243
self .log .debug ('Spawner querying job: ' + cmd )
252
244
try :
253
- out = yield self .run_command (cmd )
245
+ out = await self .run_command (cmd )
254
246
self .job_status = out
255
247
except Exception as e :
256
248
self .log .error ('Error querying job ' + self .job_id )
@@ -262,14 +254,13 @@ def read_job_state(self):
262
254
help = "Command to stop/cancel a previously submitted job. Formatted like batch_query_cmd."
263
255
).tag (config = True )
264
256
265
- @gen .coroutine
266
- def cancel_batch_job (self ):
257
+ async def cancel_batch_job (self ):
267
258
subvars = self .get_req_subvars ()
268
259
subvars ['job_id' ] = self .job_id
269
260
cmd = self .exec_prefix + ' ' + self .batch_cancel_cmd
270
261
cmd = format_template (cmd , ** subvars )
271
262
self .log .info ('Cancelling job ' + self .job_id + ': ' + cmd )
272
- yield self .run_command (cmd )
263
+ await self .run_command (cmd )
273
264
274
265
def load_state (self , state ):
275
266
"""load job_id from state"""
0 commit comments