comparison vamp-client/ProcessQtTransport.h @ 148:c3b9a584b42b

Implement timeouts
author Chris Cannam <c.cannam@qmul.ac.uk>
date Thu, 19 Jan 2017 10:49:07 +0000
parents c4f841ccb208
children
comparison
equal deleted inserted replaced
147:96488e9e9096 148:c3b9a584b42b
39 #include "SynchronousTransport.h" 39 #include "SynchronousTransport.h"
40 40
41 #include <QProcess> 41 #include <QProcess>
42 #include <QString> 42 #include <QString>
43 #include <QMutex> 43 #include <QMutex>
44 #include <QTime>
44 45
45 #include <iostream> 46 #include <iostream>
46 47
47 //#define DEBUG_TRANSPORT 1 48 //#define DEBUG_TRANSPORT 1
48 49
142 m_process->write(ptr, size); 143 m_process->write(ptr, size);
143 m_process->waitForBytesWritten(); 144 m_process->waitForBytesWritten();
144 145
145 std::vector<char> buffer; 146 std::vector<char> buffer;
146 bool complete = false; 147 bool complete = false;
148
149 QTime t;
150 t.start();
151
152 // We don't like to timeout at all while waiting for a
153 // response -- we'd like to wait as long as the server
154 // continues running.
155 //
156 int beforeResponseTimeout = 0; // ms, 0 = no timeout
157
158 // But if the call is marked as fast (i.e. just retrieving
159 // info rather than calculating something) we will time out
160 // after a bit.
161 //
162 if (!slow) beforeResponseTimeout = 10000; // ms, 0 = no timeout
163
164 // But we do timeout if the server sends part of a reply and
165 // then gets stuck. It's reasonable to assume that a server
166 // that's already prepared its message and started sending has
167 // finished doing any real work. In each case the timeout is
168 // measured since data was last read.
169 //
170 int duringResponseTimeout = 5000; // ms, 0 = no timeout
147 171
148 while (!complete) { 172 while (!complete) {
149 173
174 bool responseStarted = !buffer.empty(); // already have something
175 int ms = t.elapsed(); // time since start or since last read
176
150 qint64 byteCount = m_process->bytesAvailable(); 177 qint64 byteCount = m_process->bytesAvailable();
151 178
152 if (!byteCount) { 179 if (!byteCount) {
180
181 if (responseStarted) {
182 if (duringResponseTimeout > 0 && ms > duringResponseTimeout) {
183 log("Server timed out during response");
184 throw std::runtime_error("Request timed out");
185 }
186 } else {
187 if (beforeResponseTimeout > 0 && ms > beforeResponseTimeout) {
188 log("Server timed out before response");
189 throw std::runtime_error("Request timed out");
190 }
191 }
192
153 #ifdef DEBUG_TRANSPORT 193 #ifdef DEBUG_TRANSPORT
154 std::cerr << "waiting for data from server (slow = " << slow << ")..." << std::endl; 194 std::cerr << "waiting for data from server (slow = " << slow << ")..." << std::endl;
155 #endif 195 #endif
156 if (slow) { 196 if (slow) {
157 m_process->waitForReadyRead(1000); 197 m_process->waitForReadyRead(1000);
192 case MessageCompletenessChecker::Incomplete: break; 232 case MessageCompletenessChecker::Incomplete: break;
193 case MessageCompletenessChecker::Invalid: 233 case MessageCompletenessChecker::Invalid:
194 throw std::runtime_error 234 throw std::runtime_error
195 ("Invalid message received: corrupt stream from server?"); 235 ("Invalid message received: corrupt stream from server?");
196 } 236 }
237 (void)t.restart(); // reset timeout when we read anything
197 } 238 }
198 } 239 }
199 240
200 return buffer; 241 return buffer;
201 } 242 }