@@ -63,26 +63,30 @@ def _io_thread(self):
63
63
err_wait = select .poll ()
64
64
err_wait .register (self .process .stderr , select .POLLIN | select .POLLHUP )
65
65
66
- with open (self .output_path , "wt" ) as f :
66
+ with open (self .output_path , "wt" , buffering = 1 ) as f :
67
67
f .write ("PROCESS START: %s\n " % time .ctime ())
68
+ f .flush ()
68
69
while not self .done :
69
70
changes = out_wait .poll (0.1 )
70
71
if changes :
71
72
out_line = self .process .stdout .readline ()
72
- if not out_line :
73
+ if not out_line or out_line == " \n " :
73
74
# stdout closed (otherwise readline should have at least \n)
74
75
continue
75
76
f .write (out_line )
77
+ f .flush ()
76
78
self .output_lines .put (out_line )
77
79
78
80
changes = err_wait .poll (0 )
79
81
if changes :
80
82
err_line = self .process .stderr .readline ()
81
- if not err_line :
83
+ if not err_line or err_line == " \n " :
82
84
# stderr closed (otherwise readline should have at least \n)
83
85
continue
84
86
f .write (f"!!STDERR!! : { err_line } " )
87
+ f .flush ()
85
88
f .write ("PROCESS END: %s\n " % time .ctime ())
89
+ f .flush ()
86
90
87
91
def __enter__ (self ):
88
92
self .done = False
@@ -92,6 +96,7 @@ def __enter__(self):
92
96
stdout = subprocess .PIPE ,
93
97
stderr = subprocess .PIPE ,
94
98
text = True ,
99
+ bufsize = 1 ,
95
100
)
96
101
self .io_thread = threading .Thread (target = self ._io_thread )
97
102
self .io_thread .start ()
@@ -116,10 +121,21 @@ def __exit__(self, exception_type, exception_value, traceback):
116
121
117
122
def next_output_line (self , timeout_sec = None ):
118
123
"""Fetch an item from the output queue, potentially with a timeout."""
119
- try :
120
- return self .output_lines .get (timeout = timeout_sec )
121
- except queue .Empty :
122
- return None
124
+ end_time = time .time () + (timeout_sec if timeout_sec is not None else 0 )
125
+ sleep_duration = 0.1
126
+ while True :
127
+ remaining_time = end_time - time .time ()
128
+ if remaining_time <= 0 :
129
+ return None
130
+
131
+ if not self .output_lines .empty ():
132
+ return self .output_lines .get_nowait ()
133
+ else :
134
+ out_line = self .process .stdout .readline ()
135
+ if out_line :
136
+ self .output_lines .put (out_line )
137
+ time .sleep (sleep_duration )
138
+ sleep_duration = min (10.0 , sleep_duration * 2 )
123
139
124
140
def send_to_program (self , input_cmd ):
125
141
"""Sends the given input command string to the program.
0 commit comments