88import time
99from fractions import Fraction
1010from pathlib import Path
11- from typing import IO , Callable , Optional , Iterator
11+ from typing import IO , Callable , Optional , Iterator , Tuple
1212
1313import grpc
1414import unified_planning as up
@@ -292,15 +292,15 @@ class Aries(AriesEngine, mixins.OneshotPlannerMixin, mixins.AnytimePlannerMixin)
292292 def name (self ) -> str :
293293 return "aries"
294294
295- def _solve (
295+ def _prepare_solving (
296296 self ,
297297 problem : "up.model.AbstractProblem" ,
298298 heuristic : Optional [
299299 Callable [["up.model.state.ROState" ], Optional [float ]]
300300 ] = None ,
301301 timeout : Optional [float ] = None ,
302302 output_stream : Optional [IO [str ]] = None ,
303- ) -> "up.engines.results.PlanGenerationResult" :
303+ ) -> Tuple [ "_Server" , proto . PlanRequest ] :
304304 # Assert that the problem is a valid problem
305305 assert isinstance (problem , up .model .AbstractProblem )
306306 if heuristic is not None :
@@ -312,9 +312,15 @@ def _solve(
312312 # Note: when the `server` object is garbage collected, the process will be killed
313313 server = _Server (self ._executable , output_stream = output_stream )
314314 proto_problem = self ._writer .convert (problem )
315-
316315 req = proto .PlanRequest (problem = proto_problem , timeout = timeout )
317- response = server .planner .planOneShot (req )
316+
317+ return server , req
318+
319+ def _process_response (
320+ self ,
321+ response : proto .PlanGenerationResult ,
322+ problem : "up.model.AbstractProblem" ,
323+ ) -> "up.engines.results.PlanGenerationResult" :
318324 response = self ._reader .convert (response , problem )
319325
320326 # if we have a time triggered plan and a recent version of the UP that support setting epsilon-separation,
@@ -330,24 +336,29 @@ def _solve(
330336
331337 return response
332338
339+ def _solve (
340+ self ,
341+ problem : "up.model.AbstractProblem" ,
342+ heuristic : Optional [
343+ Callable [["up.model.state.ROState" ], Optional [float ]]
344+ ] = None ,
345+ timeout : Optional [float ] = None ,
346+ output_stream : Optional [IO [str ]] = None ,
347+ ) -> "up.engines.results.PlanGenerationResult" :
348+ server , req = self ._prepare_solving (problem , heuristic , timeout , output_stream )
349+ response = server .planner .planOneShot (req )
350+ return self ._process_response (response , problem )
351+
333352 def _get_solutions (
334353 self ,
335354 problem : "up.model.AbstractProblem" ,
336355 timeout : Optional [float ] = None ,
337356 output_stream : Optional [IO [str ]] = None ,
338357 ) -> Iterator ["up.engines.results.PlanGenerationResult" ]:
339- # Assert that the problem is a valid problem
340- assert isinstance (problem , up .model .AbstractProblem )
341-
342- # start a gRPC server in its own process
343- # Note: when the `server` object is garbage collected, the process will be killed
344- server = _Server (self ._executable , output_stream = output_stream )
345- proto_problem = self ._writer .convert (problem )
346-
347- req = proto .PlanRequest (problem = proto_problem , timeout = timeout )
358+ server , req = self ._prepare_solving (problem , None , timeout , output_stream )
348359 stream = server .planner .planAnytime (req )
349360 for response in stream :
350- response = self ._reader . convert (response , problem )
361+ response = self ._process_response (response , problem )
351362 yield response
352363 # The parallel solver implementation in aries are such that intermediate answer might arrive late
353364 if response .status != PlanGenerationResultStatus .INTERMEDIATE :
0 commit comments