Ignore:
Timestamp:
10/26/17 10:23:17 (7 years ago)
Author:
rlacroix
Message:

Fix: Handle end-of-file correctly for files in read mode.

Previously desynchronizations between clients could occur, leading to invalid events being received by the server(s).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/node/field.cpp

    r1315 r1318  
    3838      , hasTimeInstant(false) 
    3939      , hasTimeCentered(false) 
     40      , wasDataRequestedFromServer(false) 
    4041      , wasDataAlreadyReceivedFromServer(false) 
    4142      , isEOF(false) 
     
    5253      , hasTimeInstant(false) 
    5354      , hasTimeCentered(false) 
     55      , wasDataRequestedFromServer(false) 
    5456      , wasDataAlreadyReceivedFromServer(false) 
    5557      , isEOF(false) 
     
    261263    lastDataRequestedFromServer = tsDataRequested; 
    262264 
    263     if (!isEOF) // No need to send the request if we already know we are at EOF 
     265    // No need to send the request if we are sure that we are already at EOF 
     266    if (!isEOF || context->getCalendar()->getCurrentDate() <= dateEOF) 
    264267    { 
    265268      CEventClient event(getType(), EVENT_ID_READ_DATA); 
     
    277280    else 
    278281      serverSourceFilter->signalEndOfStream(tsDataRequested); 
     282 
     283    wasDataRequestedFromServer = true; 
    279284 
    280285    return !isEOF; 
     
    433438  { 
    434439    CContext* context = CContext::getCurrent(); 
    435     int record; 
    436440    std::map<int, CArray<double,1> > data; 
     441    const bool wasEOF = isEOF; 
    437442 
    438443    for (int i = 0; i < ranks.size(); i++) 
    439444    { 
    440445      int rank = ranks[i]; 
     446      int record; 
    441447      *buffers[i] >> record; 
    442448      isEOF = (record == int(-1)); 
     
    457463 
    458464    if (isEOF) 
     465    { 
     466      if (!wasEOF) 
     467        dateEOF = lastDataReceivedFromServer; 
     468 
    459469      serverSourceFilter->signalEndOfStream(lastDataReceivedFromServer); 
     470    } 
    460471    else 
    461472      serverSourceFilter->streamDataFromServer(lastDataReceivedFromServer, data); 
     473  } 
     474 
     475  void CField::checkForLateDataFromServer(void) 
     476  { 
     477    CContext* context = CContext::getCurrent(); 
     478    const CDate& currentDate = context->getCalendar()->getCurrentDate(); 
     479 
     480    // Check if data previously requested has been received as expected 
     481    if (wasDataRequestedFromServer && (!isEOF || context->getCalendar()->getCurrentDate() <= dateEOF)) 
     482    { 
     483      CTimer timer("CField::checkForLateDataFromServer"); 
     484 
     485      bool isDataLate = !wasDataAlreadyReceivedFromServer || lastDataReceivedFromServer + file->output_freq < currentDate; 
     486      while (isDataLate && timer.getCumulatedTime() < CXios::recvFieldTimeout) 
     487      { 
     488        timer.resume(); 
     489 
     490        context->checkBuffersAndListen(); 
     491 
     492        timer.suspend(); 
     493 
     494        isDataLate = !wasDataAlreadyReceivedFromServer || lastDataReceivedFromServer + file->output_freq < currentDate; 
     495      } 
     496 
     497      if (isDataLate) 
     498        ERROR("void CField::checkForLateDataFromServer(void)", 
     499              << "Late data at timestep = " << currentDate); 
     500    } 
    462501  } 
    463502 
Note: See TracChangeset for help on using the changeset viewer.