source: XIOS/dev/dev_ym/XIOS_SERVICES/src/manager/services.cpp @ 1761

Last change on this file since 1761 was 1761, checked in by ymipsl, 5 years ago

implementing first guess for service functionnalities.

YM

  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 4.6 KB
Line 
1#include "services.hpp"
2#include "services_manager.hpp"
3#include "mpi.hpp"
4#include "cxios.hpp"
5#include "server_context.hpp"
6#include "event_scheduler.hpp"
7
8namespace xios
9{
10  CService::CService(MPI_Comm serviceComm, const std::string& poolId, const std::string& serviceId, const int& partitionId, 
11                     int type, int nbPartitions) : finalizeSignal_(false), eventScheduler_(nullptr), poolId_(poolId), serviceId_(serviceId),
12                                                   partitionId_(partitionId), type_(type), nbPartitions_(nbPartitions)
13
14
15  {
16    int localRank, globalRank, commSize ;
17
18    MPI_Comm_dup(serviceComm, &serviceComm_) ;
19    MPI_Comm globalComm_=CXios::getXiosComm() ;
20 
21    MPI_Comm_rank(globalComm_,&globalRank) ;
22    MPI_Comm_rank(serviceComm_,&localRank) ;
23   
24    winNotify_ = new CWindowManager(serviceComm_, maxBufferSize_) ;
25    winNotify_->lockWindow(localRank,0) ;
26    winNotify_->updateToWindow(localRank, this, &CService::createContextDumpOut) ;
27    winNotify_->unlockWindow(localRank,0) ;
28
29    if (localRank==localLeader_) 
30    {
31      globalLeader_=globalRank ;
32      MPI_Comm_rank(serviceComm_,&commSize) ;
33      CXios::getServicesManager()->registerService(poolId, serviceId, partitionId, type, commSize, nbPartitions, globalLeader_) ;
34    }
35    eventScheduler_ = new CEventScheduler(serviceComm_) ;
36  }
37
38  void CService::createContext( const std::string& poolId, const std::string& serviceId, const int& partitionId, const std::string& contextId)
39  {
40    int commSize ;
41    MPI_Comm_size(serviceComm_, &commSize) ;
42   
43    for(int rank=0; rank<commSize; rank++) createContextNotify(rank, poolId, serviceId, partitionId, contextId) ;
44  }
45/*
46  void CService::createContext(const std::string& contextId)
47  {
48    contexts_[contextId] = new CServerContext(this, serviceComm_, poolId_, serviceId_, partitionId_, contextId) ;
49  }
50*/
51  void CService::createContextNotify(int rank, const std::string& poolId, const std::string& serviceId, const int& partitionId, const std::string& contextId)
52  {
53    winNotify_->lockWindow(rank,0) ;
54    winNotify_->updateFromWindow(rank, this, &CService::createContextDumpIn) ;
55    notifications_.push_back(std::make_tuple(poolId, serviceId, partitionId, contextId)) ;
56    winNotify_->updateToWindow(rank, this, &CService::createContextDumpOut) ; 
57    winNotify_->unlockWindow(rank,0) ;   
58  }
59
60
61  void CService::createContextDumpOut(CBufferOut& buffer)
62  {
63    buffer.realloc(maxBufferSize_) ;
64   
65    buffer << (int) (notifications_.size());
66   
67    for(auto it=notifications_.begin();it!=notifications_.end(); ++it) 
68      buffer << std::get<0>(*it) << std::get<1>(*it) << std::get<2>(*it) << std::get<3>(*it)  ;
69  }
70
71
72  void CService::createContextDumpIn(CBufferIn& buffer)
73  {
74    std::string poolId ;
75    std::string serviceId ;
76    int partitionId ;
77    std::string contextId ;
78   
79    notifications_.clear() ;
80    int nbNotifications ;
81    buffer>>nbNotifications ;
82    for(int i=0;i<nbNotifications;i++) 
83    {
84      buffer>>poolId>>serviceId>>partitionId>>contextId ;
85      notifications_.push_back(std::make_tuple(poolId, serviceId, partitionId, contextId)) ;
86    }
87  }
88
89  bool CService::eventLoop(void)
90  {
91    checkCreateContextNotification() ;
92    eventScheduler_->checkEvent() ;
93    for(auto it=contexts_.begin();it!=contexts_.end();++it) 
94    {
95      if (it->second->eventLoop())
96      {
97        contexts_.erase(it) ;
98        // destroy server_context -> to do later
99        break ;
100      } ;
101    }
102
103    if (contexts_.empty() && finalizeSignal_) return true ;
104    else return false ;
105  }
106
107  void CService::checkCreateContextNotification(void)
108  {
109    int commRank ;
110    MPI_Comm_rank(serviceComm_, &commRank) ;
111    winNotify_->lockWindow(commRank,0) ;
112    winNotify_->updateFromWindow(commRank, this, &CService::createContextDumpIn) ;
113   
114    if (!notifications_.empty())
115    {
116      auto info = notifications_.front() ;
117      createNewContext(get<0>(info), get<1>(info), get<2>(info), get<3>(info)) ;
118      notifications_.pop_front() ;
119      winNotify_->updateToWindow(commRank, this, &CService::createContextDumpOut) ;     
120    }
121    winNotify_->unlockWindow(commRank,0) ;
122  }
123
124   void CService::createNewContext(const std::string& poolId, const std::string& serviceId, const int& partitionId, const std::string& contextId)
125   {
126     contexts_[contextId] = new CServerContext(this, serviceComm_, poolId, serviceId, partitionId, contextId) ; 
127   }
128
129  void CService::finalizeSignal(void)
130  {
131    finalizeSignal_=true ;
132    for(auto it=contexts_.begin();it!=contexts_.end();++it) it->second->finalizeSignal() ;
133  }
134
135  CEventScheduler* CService::getEventScheduler(void)
136  {
137    return eventScheduler_ ;
138  }
139}
Note: See TracBrowser for help on using the repository browser.