Changeset 21:0b447152d28b for src
- Timestamp:
- 02/14/12 19:14:23 (13 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/checks.py
r13 r21 438 438 if state.timestamp>=(self._faultStarted + timeout): 439 439 self.logFault(flight, aircraft, logger, oldState, state) 440 self._faulted = True441 440 self._faultStarted = state.timestamp 442 441 else: -
src/fsuipc.py
r16 r21 58 58 return None 59 59 60 NUM_READATTEMPTS = 3 61 62 @staticmethod 63 def _performRead(data, callback, extra, validator): 64 """Perform a read request. 65 66 If there is a validator, that will be called with the return values, 67 and if the values are wrong, the request is retried at most a certain 68 number of times. 69 70 Return True if the request has succeeded, False if validation has 71 failed during all attempts. An exception may also be thrown if there is 72 some lower-level communication problem.""" 73 attemptsLeft = Handler.NUM_READATTEMPTS 74 while attemptsLeft>0: 75 values = pyuipc.read(data) 76 if validator is None or \ 77 Handler._callSafe(lambda: validator(values, extra)): 78 Handler._callSafe(lambda: callback(values, extra)) 79 return True 80 else: 81 attemptsLeft -= 1 82 return False 83 60 84 class Request(object): 61 85 """A simple, one-shot request.""" 62 def __init__(self, forWrite, data, callback, extra ):86 def __init__(self, forWrite, data, callback, extra, validator = None): 63 87 """Construct the request.""" 64 88 self._forWrite = forWrite … … 66 90 self._callback = callback 67 91 self._extra = extra 92 self._validator = validator 68 93 69 94 def process(self, time): 70 """Process the request.""" 95 """Process the request. 96 97 Return True if the request has succeeded, False if data validation 98 has failed for a reading request. An exception may also be thrown 99 if there is some lower-level communication problem.""" 71 100 if self._forWrite: 72 101 pyuipc.write(self._data) 73 102 Handler._callSafe(lambda: self._callback(True, self._extra)) 103 return True 74 104 else: 75 values = pyuipc.read(self._data) 76 Handler._callSafe(lambda: self._callback(values, self._extra)) 77 78 return True 105 return Handler._performRead(self._data, self._callback, 106 self._extra, self._validator) 79 107 80 108 def fail(self): … … 87 115 class PeriodicRequest(object): 88 116 """A periodic request.""" 89 def __init__(self, id, period, data, callback, extra ):117 def __init__(self, id, period, data, callback, extra, validator): 90 118 """Construct the periodic request.""" 91 119 self._id = id … … 96 124 self._callback = callback 97 125 self._extra = extra 126 self._validator = validator 98 127 99 128 @property … … 110 139 """Check if this request should be executed, and if so, do so. 111 140 112 Return a boolean indicating if the request was executed.""" 113 if time < self._nextFire: 114 return False 115 141 time is the time at which the request is being executed. If this 142 function is called too early, nothing is done, and True is 143 returned. 144 145 Return True if the request has succeeded, False if data validation 146 has failed. An exception may also be thrown if there is some 147 lower-level communication problem.""" 148 if time<self._nextFire: 149 return True 150 116 151 if self._preparedData is None: 117 152 self._preparedData = pyuipc.prepare_data(self._data) 118 153 self._data = None 119 120 values = pyuipc.read(self._preparedData)121 122 Handler._callSafe(lambda: self._callback(values, self._extra)) 123 124 while self._nextFire <= time:125 self._nextFire += self._period154 155 isOK = Handler._performRead(self._preparedData, self._callback, 156 self._extra, self._validator) 157 158 if isOK: 159 while self._nextFire <= time: 160 self._nextFire += self._period 126 161 127 return True162 return isOK 128 163 129 164 def fail(self): … … 144 179 self._requestCondition = threading.Condition() 145 180 self._connectionRequested = False 181 self._connected = False 146 182 147 183 self._requests = [] … … 151 187 self.daemon = True 152 188 153 def requestRead(self, data, callback, extra = None ):189 def requestRead(self, data, callback, extra = None, validator = None): 154 190 """Request the reading of some data. 155 191 … … 165 201 """ 166 202 with self._requestCondition: 167 self._requests.append(Handler.Request(False, data, callback, extra)) 203 self._requests.append(Handler.Request(False, data, callback, extra, 204 validator)) 168 205 self._requestCondition.notify() 169 206 … … 192 229 condition.notify() 193 230 194 def read(self, data): 195 """Read the given data synchronously. 196 197 If a problem occurs, an exception is thrown.""" 198 with threading.Condition() as condition: 199 extra = [condition] 200 self._requestRead(data, self._readWriteCallback, extra) 201 while len(extra)<2: 202 condition.wait() 203 if extra[1] is None: 204 raise fs.SimulatorException("reading failed") 205 else: 206 return extra[1] 207 208 def write(self, data): 209 """Write the given data synchronously. 210 211 If a problem occurs, an exception is thrown.""" 212 with threading.Condition() as condition: 213 extra = [condition] 214 self._requestWrite(data, self._writeCallback, extra) 215 while len(extra)<2: 216 condition.wait() 217 if extra[1] is None: 218 raise fs.SimulatorException("writing failed") 219 220 def requestPeriodicRead(self, period, data, callback, extra = None): 231 def requestPeriodicRead(self, period, data, callback, extra = None, 232 validator = None): 221 233 """Request a periodic read of data. 222 234 … … 228 240 id = self._nextPeriodicID 229 241 self._nextPeriodicID += 1 230 request = Handler.PeriodicRequest(id, period, data, callback, extra) 242 request = Handler.PeriodicRequest(id, period, data, callback, 243 extra, validator) 231 244 self._periodicRequests.append(request) 232 245 self._requestCondition.notify() … … 273 286 274 287 def _connect(self): 275 """Try to connect to the flight simulator via FSUIPC""" 288 """Try to connect to the flight simulator via FSUIPC 289 290 Returns True if the connection has been established, False if it was 291 not due to no longer requested. 292 """ 276 293 while self._connectionRequested: 277 294 try: … … 283 300 self._connectionListener.connected(const.SIM_MSFS9, 284 301 description)) 302 self._connected = True 285 303 return True 286 304 except Exception, e: … … 294 312 with self._requestCondition: 295 313 while self._connectionRequested: 296 if not self._processRequests(): 297 return 298 timeout = None 299 if self._periodicRequests: 300 self._periodicRequests.sort() 301 timeout = self._periodicRequests[0].nextFire - time.time() 302 if timeout is None or timeout > 0.0: 303 self._requestCondition.wait(timeout) 314 self._processRequests() 315 self._waitRequest() 316 317 def _waitRequest(self): 318 """Wait for the time of the next request. 319 320 Returns also, if the connection is no longer requested. 321 322 Should be called with the request condition lock held.""" 323 while self._connectionRequested: 324 timeout = None 325 if self._periodicRequests: 326 self._periodicRequests.sort() 327 timeout = self._periodicRequests[0].nextFire - time.time() 328 329 if timeout is not None and timeout <= 0.0: 330 return 331 332 self._requestCondition.wait(timeout) 304 333 305 334 def _disconnect(self): 306 335 """Disconnect from the flight simulator.""" 307 pyuipc.close() 308 Handler._callSafe(lambda: self._connectionListener.disconnected()) 336 if self._connected: 337 pyuipc.close() 338 Handler._callSafe(lambda: self._connectionListener.disconnected()) 339 self._connected = False 309 340 310 341 def _failRequests(self, request): … … 323 354 """Process the given request. 324 355 325 If an exception occurs, we try to reconnect. 326 327 Returns what the request's process() function returned or None if 328 reconnection failed.""" 356 If an exception occurs or invalid data is read too many times, we try 357 to reconnect. 358 359 This function returns only if the request has succeeded, or if a 360 connection is no longer requested. 361 362 This function is called with the request lock held, but is relased 363 whole processing the request and reconnecting.""" 329 364 self._requestCondition.release() 330 365 366 needReconnect = False 331 367 try: 332 return request.process(time) 333 except Exception as e: 334 print "fsuipc.Handler._processRequest: FSUIPC connection failed (" + \ 335 str(e) + ") reconnecting." 336 self._disconnect() 337 self._failRequests(request) 338 if not self._connect(): return None 339 else: return True 368 try: 369 if not request.process(time): 370 print "fsuipc.Handler._processRequest: FSUIPC returned invalid data too many times, reconnecting" 371 needReconnect = True 372 except Exception as e: 373 print "fsuipc.Handler._processRequest: FSUIPC connection failed (" + \ 374 str(e) + "), reconnecting." 375 needReconnect = True 376 377 if needReconnect: 378 self._disconnect() 379 self._failRequests(request) 380 self._connect() 340 381 finally: 341 382 self._requestCondition.acquire() … … 348 389 self._periodicRequests.sort() 349 390 request = self._periodicRequests[0] 350 result = self._processRequest(request, time.time()) 351 if result is None: return False 352 elif not result: break 391 392 t = time.time() 393 394 if request.nextFire>t: 395 break 396 397 self._processRequest(request, t) 353 398 354 399 while self._connectionRequested and self._requests: … … 356 401 del self._requests[0] 357 402 358 if self._processRequest(request, None) is None: 359 return False 403 self._processRequest(request, None) 360 404 361 405 return self._connectionRequested … … 481 525 """Start the default normal periodic request.""" 482 526 assert self._normalRequestID is None 483 self._normalRequestID = self._handler.requestPeriodicRead(1.0, 484 Simulator.normalData, 485 self._handleNormal) 527 self._normalRequestID = \ 528 self._handler.requestPeriodicRead(1.0, 529 Simulator.normalData, 530 self._handleNormal, 531 validator = self._validateNormal) 486 532 487 533 def _stopNormal(self): … … 491 537 self._normalRequestID = None 492 538 self._monitoring = False 539 540 def _validateNormal(self, data, extra): 541 """Validate the normal data.""" 542 return data[0]!=0 and data[1]!=0 and len(data[5])>0 and len(data[6])>0 493 543 494 544 def _handleNormal(self, data, extra): … … 565 615 self._normalRequestID = \ 566 616 self._handler.requestPeriodicRead(1.0, data, 567 self._handleNormal) 617 self._handleNormal, 618 validator = self._validateNormal) 568 619 self._monitoring = True 569 620 -
src/logger.py
r17 r21 73 73 self.message(timestamp, "%s (NO GO)" % (what)) 74 74 else: 75 self.message(timestamp, "%s (% f)" % (what, score))75 self.message(timestamp, "%s (%.1f)" % (what, score)) 76 76 77 77 def noGo(self, faultID, timestamp, what, shortReason):
Note:
See TracChangeset
for help on using the changeset viewer.