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/dev/XIOS_DEV_CMIP6/src/node/field.cpp

    r1315 r1318  
    4040      , hasTimeInstant(false) 
    4141      , hasTimeCentered(false) 
     42      , wasDataRequestedFromServer(false) 
    4243      , wasDataAlreadyReceivedFromServer(false) 
    4344      , isEOF(false), nstepMaxRead(false) 
     
    5556      , hasTimeInstant(false) 
    5657      , hasTimeCentered(false) 
     58      , wasDataRequestedFromServer(false) 
    5759      , wasDataAlreadyReceivedFromServer(false) 
    5860      , isEOF(false), nstepMaxRead(false) 
     
    291293    lastDataRequestedFromServer = tsDataRequested; 
    292294 
    293     if (!isEOF) // No need to send the request if we already know we are at EOF 
     295    // No need to send the request if we are sure that we are already at EOF 
     296    if (!isEOF || context->getCalendar()->getCurrentDate() <= dateEOF) 
    294297    { 
    295298      CEventClient event(getType(), EVENT_ID_READ_DATA); 
     
    307310    else 
    308311      serverSourceFilter->signalEndOfStream(tsDataRequested); 
     312 
     313    wasDataRequestedFromServer = true; 
    309314 
    310315    return !isEOF; 
     
    520525  { 
    521526    CContext* context = CContext::getCurrent(); 
    522     int record; 
    523527    std::map<int, CArray<double,1> > data; 
     528    const bool wasEOF = isEOF; 
    524529 
    525530    for (int i = 0; i < ranks.size(); i++) 
    526531    { 
    527532      int rank = ranks[i]; 
     533      int record; 
    528534      *buffers[i] >> record; 
    529535      isEOF = (record == int(-1)); 
     
    544550 
    545551    if (isEOF) 
     552    { 
     553      if (!wasEOF) 
     554        dateEOF = lastDataReceivedFromServer; 
     555 
    546556      serverSourceFilter->signalEndOfStream(lastDataReceivedFromServer); 
     557    } 
    547558    else 
    548559      serverSourceFilter->streamDataFromServer(lastDataReceivedFromServer, data); 
     560  } 
     561 
     562  void CField::checkForLateDataFromServer(void) 
     563  { 
     564    CContext* context = CContext::getCurrent(); 
     565    const CDate& currentDate = context->getCalendar()->getCurrentDate(); 
     566 
     567    // Check if data previously requested has been received as expected 
     568    if (wasDataRequestedFromServer && (!isEOF || context->getCalendar()->getCurrentDate() <= dateEOF)) 
     569    { 
     570      CTimer timer("CField::checkForLateDataFromServer"); 
     571 
     572      bool isDataLate = !wasDataAlreadyReceivedFromServer || lastDataReceivedFromServer + file->output_freq < currentDate; 
     573      while (isDataLate && timer.getCumulatedTime() < CXios::recvFieldTimeout) 
     574      { 
     575        timer.resume(); 
     576 
     577        context->checkBuffersAndListen(); 
     578 
     579        timer.suspend(); 
     580 
     581        isDataLate = !wasDataAlreadyReceivedFromServer || lastDataReceivedFromServer + file->output_freq < currentDate; 
     582      } 
     583 
     584      if (isDataLate) 
     585        ERROR("void CField::checkForLateDataFromServer(void)", 
     586              << "Late data at timestep = " << currentDate); 
     587    } 
    549588  } 
    550589 
Note: See TracChangeset for help on using the changeset viewer.