15 #include <pv/createRequest.h> 17 #define epicsExportSharedSymbols 25 namespace epics {
namespace pvaClient {
28 class epicsShareClass PvaClientGetCache
34 if(PvaClient::getDebug()) cout <<
"PvaClientGetCache::~PvaClientGetCache\n";
37 void addGet(
string const & request,
PvaClientGetPtr const & pvaClientGet);
41 map<string,PvaClientGetPtr> pvaClientGetMap;
46 map<string,PvaClientGetPtr>::iterator iter = pvaClientGetMap.find(request);
47 if(iter!=pvaClientGetMap.end())
return iter->second;
51 void PvaClientGetCache::addGet(
string const & request,
PvaClientGetPtr const & pvaClientGet)
53 map<string,PvaClientGetPtr>::iterator iter = pvaClientGetMap.find(request);
54 if(iter!=pvaClientGetMap.end()) {
55 throw std::runtime_error(
"pvaClientGetCache::addGet pvaClientGet already cached");
57 pvaClientGetMap.insert(std::pair<string,PvaClientGetPtr>(request,pvaClientGet));
60 void PvaClientGetCache::showCache()
62 map<string,PvaClientGetPtr>::iterator iter;
63 for(iter = pvaClientGetMap.begin(); iter != pvaClientGetMap.end(); ++iter)
65 cout <<
" " << iter->first << endl;
69 size_t PvaClientGetCache::cacheSize()
71 return pvaClientGetMap.size();
75 class epicsShareClass PvaClientPutCache
81 if(PvaClient::getDebug()) cout <<
"PvaClientPutCache::~PvaClientPutCache\n";
84 void addPut(
string const & request,
PvaClientPutPtr const & pvaClientPut);
88 map<string,PvaClientPutPtr> pvaClientPutMap;
94 map<string,PvaClientPutPtr>::iterator iter = pvaClientPutMap.find(request);
95 if(iter!=pvaClientPutMap.end())
return iter->second;
99 void PvaClientPutCache::addPut(
string const & request,
PvaClientPutPtr const & pvaClientPut)
101 map<string,PvaClientPutPtr>::iterator iter = pvaClientPutMap.find(request);
102 if(iter!=pvaClientPutMap.end()) {
103 throw std::runtime_error(
"pvaClientPutCache::addPut pvaClientPut already cached");
105 pvaClientPutMap.insert(std::pair<string,PvaClientPutPtr>(
106 request,pvaClientPut));
109 void PvaClientPutCache::showCache()
111 map<string,PvaClientPutPtr>::iterator iter;
112 for(iter = pvaClientPutMap.begin(); iter != pvaClientPutMap.end(); ++iter)
114 cout <<
" " << iter->first << endl;
118 size_t PvaClientPutCache::cacheSize()
120 return pvaClientPutMap.size();
126 string const & channelName,
127 string const & providerName)
134 PvaClientChannel::PvaClientChannel(
136 string const & channelName,
137 string const & providerName)
138 : pvaClient(pvaClient),
139 channelName(channelName),
140 providerName(providerName),
141 connectState(connectIdle),
142 createRequest(CreateRequest::create()),
143 pvaClientGetCache(
new PvaClientGetCache()),
144 pvaClientPutCache(
new PvaClientPutCache())
146 if(PvaClient::getDebug()) {
147 cout <<
"PvaClientChannel::PvaClientChannel channelName " << channelName << endl;
151 PvaClientChannel::~PvaClientChannel()
153 if(PvaClient::getDebug()) {
154 cout <<
"PvaClientChannel::~PvaClientChannel() " 155 <<
" channelName " << channelName
158 if(PvaClient::getDebug()) showCache();
161 void PvaClientChannel::channelCreated(
const Status& status, Channel::shared_pointer
const & channel)
163 if(PvaClient::getDebug()) {
164 cout <<
"PvaClientChannel::channelCreated" 165 <<
" channelName " << channelName
166 <<
" connectState " << connectState
167 <<
" isConnected " << (channel->isConnected() ?
"true" :
"false")
168 <<
" status.isOK " << (status.isOK() ?
"true" :
"false")
172 this->channel = channel;
173 if(connectState==connected)
return;
174 if(connectState!=connectActive) {
175 string message(
"PvaClientChannel::channelCreated");
176 message +=
" channel " + channelName
177 +
" why was this called when connectState!=ConnectState.connectActive";
178 throw std::runtime_error(message);
181 string message(
"PvaClientChannel::channelCreated");
182 +
" status " + status.getMessage() +
" why??";
183 throw std::runtime_error(message);
187 void PvaClientChannel::channelStateChange(
188 Channel::shared_pointer
const & channel,
189 Channel::ConnectionState connectionState)
191 if(PvaClient::getDebug()) {
192 cout <<
" PvaClientChannel::channelStateChange " 193 <<
" channelName " << channelName
194 <<
" " << Channel::ConnectionStateNames[connectionState]
197 bool waitingForConnect =
false;
198 if(connectState==connectActive) waitingForConnect =
true;
199 if(connectionState!=Channel::CONNECTED) {
201 connectState = notConnected;
204 this->channel = channel;
205 connectState = connected;
207 if(waitingForConnect) {
209 waitForConnect.signal();
213 bool value = (connectionState==Channel::CONNECTED ? true :
false);
214 req->channelStateChange(shared_from_this(),value);
218 string PvaClientChannel::getRequesterName()
221 if(!yyy)
return string(
"PvaClientChannel::getRequesterName() PvaClient isDestroyed");
222 return yyy->getRequesterName();
225 void PvaClientChannel::message(
226 string const & message,
227 MessageType messageType)
231 yyy->message(channelName +
" " + message, messageType);
234 string PvaClientChannel::getChannelName()
239 Channel::shared_pointer PvaClientChannel::getChannel()
244 void PvaClientChannel::setStateChangeRequester(
247 this->stateChangeRequester = stateChangeRequester;
248 bool isConnected =
false;
249 if(channel) isConnected = channel->isConnected();
250 stateChangeRequester->channelStateChange(shared_from_this(),isConnected);
253 void PvaClientChannel::connect(
double timeout)
255 if(PvaClient::getDebug()) {
256 cout <<
"PvaClientChannel::connect" 257 <<
" channelName " << channelName << endl;
260 Status status = waitConnect(timeout);
261 if(status.isOK())
return;
262 if(PvaClient::getDebug()) cout <<
"PvaClientChannel::connect waitConnect failed\n";
263 string message = string(
"channel ") + channelName
264 +
" PvaClientChannel::connect " + status.getMessage();
265 throw std::runtime_error(message);
268 void PvaClientChannel::issueConnect()
270 if(PvaClient::getDebug()) {
271 cout <<
"PvaClientChannel::issueConnect" 272 <<
" channelName " << channelName << endl;
276 if(connectState==connected)
return;
277 if(connectState!=connectIdle) {
278 throw std::runtime_error(
"pvaClientChannel already connected");
280 connectState = connectActive;
282 ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients());
283 channelProvider = reg->getProvider(providerName);
284 if(!channelProvider) {
285 throw std::runtime_error(channelName +
" provider " + providerName +
" not registered");
287 if(PvaClient::getDebug()) cout <<
"PvaClientChannel::issueConnect calling provider->createChannel\n";
288 channel = channelProvider->createChannel(channelName,shared_from_this(),ChannelProvider::PRIORITY_DEFAULT);
290 throw std::runtime_error(channelName +
" channelCreate failed ");
294 Status PvaClientChannel::waitConnect(
double timeout)
296 if(PvaClient::getDebug()) {
297 cout <<
"PvaClientChannel::waitConnect" 298 <<
" channelName " << channelName << endl;
302 if(!channel)
return Status(Status::STATUSTYPE_ERROR,
"");
303 if(channel->isConnected())
return Status::Ok;
306 waitForConnect.wait(timeout);
308 waitForConnect.wait();
310 if(!channel)
return Status(Status::STATUSTYPE_ERROR,
"pvaClientChannel::waitConnect channel is null");
311 if(channel->isConnected())
return Status::Ok;
312 return Status(Status::STATUSTYPE_ERROR,
" not connected");
317 PVStructurePtr pvRequest = createRequest->createRequest(request);
319 string message = string(
"channel ") + channelName
320 +
" PvaClientChannel::createProcess invalid pvRequest: " 321 + createRequest->getMessage();
322 throw std::runtime_error(message);
324 return createProcess(pvRequest);
329 if(connectState!=connected) connect(5.0);
331 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
332 return PvaClientProcess::create(yyy,shared_from_this(),pvRequest);
340 pvaClientGet = createGet(request);
341 pvaClientGet->connect();
342 pvaClientGetCache->addGet(request,pvaClientGet);
351 PVStructurePtr pvRequest = createRequest->createRequest(request);
353 string message = string(
"channel ") + channelName
354 +
" PvaClientChannel::createGet invalid pvRequest: " 355 + createRequest->getMessage();
356 throw std::runtime_error(message);
358 return createGet(pvRequest);
361 PvaClientGetPtr PvaClientChannel::createGet(PVStructurePtr
const & pvRequest)
363 if(connectState!=connected) connect(5.0);
365 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
366 return PvaClientGet::create(yyy,shared_from_this(),pvRequest);
369 double PvaClientChannel::getDouble(
string const & request)
371 return get(request)->getData()->getDouble();
374 string PvaClientChannel::getString(
string const & request)
376 return get(request)->getData()->getString();
379 shared_vector<const double> PvaClientChannel::getDoubleArray(
string const & request)
381 return get(request)->getData()->getDoubleArray();
384 shared_vector<const std::string> PvaClientChannel::getStringArray(
string const & request)
386 return get(request)->getData()->getStringArray();
393 if(pvaClientPut)
return pvaClientPut;
395 pvaClientPut = createPut(request);
396 pvaClientPut->connect();
398 pvaClientPutCache->addPut(request,pvaClientPut);
406 PVStructurePtr pvRequest = createRequest->createRequest(request);
408 string message = string(
"channel ") + channelName
409 +
" PvaClientChannel::createPut invalid pvRequest: " 410 + createRequest->getMessage();
411 throw std::runtime_error(message);
413 return createPut(pvRequest);
416 PvaClientPutPtr PvaClientChannel::createPut(PVStructurePtr
const & pvRequest)
418 if(connectState!=connected) connect(5.0);
420 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
421 return PvaClientPut::create(yyy,shared_from_this(),pvRequest);
424 void PvaClientChannel::putDouble(
double value,
string const & request)
428 putData->putDouble(value); clientPut->put();
431 void PvaClientChannel::putString(std::string
const & value,
string const & request)
435 putData->putString(value); clientPut->put();
438 void PvaClientChannel::putDoubleArray(
439 shared_vector<const double>
const & value,
440 string const & request)
444 size_t n = value.size();
445 shared_vector<double> valueArray(n);
446 for(
size_t i=0; i<n; ++i) valueArray[i] = value[i];
447 putData->putDoubleArray(freeze(valueArray)); clientPut->put();
450 void PvaClientChannel::putStringArray(
451 shared_vector<const string>
const & value,
452 string const & request)
456 size_t n = value.size();
457 shared_vector<string> valueArray(n);
458 for(
size_t i=0; i<n; ++i) valueArray[i] = value[i];
459 putData->putStringArray(freeze(valueArray)); clientPut->put();
464 PVStructurePtr pvRequest = createRequest->createRequest(request);
466 string message = string(
"channel ") + channelName
467 +
" PvaClientChannel::createPutGet invalid pvRequest: " 468 + createRequest->getMessage();
469 throw std::runtime_error(message);
471 return createPutGet(pvRequest);
476 if(connectState!=connected) connect(5.0);
478 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
479 return PvaClientPutGet::create(yyy,shared_from_this(),pvRequest);
485 pvaClientMonitor->connect();
486 pvaClientMonitor->start();
487 return pvaClientMonitor;
492 return monitor(
"field(value,alarm,timeStamp)",pvaClientMonitorRequester);
499 pvaClientMonitor->connect();
500 pvaClientMonitor->setRequester(pvaClientMonitorRequester);
501 pvaClientMonitor->start();
502 return pvaClientMonitor;
507 PVStructurePtr pvRequest = createRequest->createRequest(request);
509 string message = string(
"channel ") + channelName
510 +
" PvaClientChannel::createMonitor invalid pvRequest: " 511 + createRequest->getMessage();
512 throw std::runtime_error(message);
514 return createMonitor(pvRequest);
519 if(connectState!=connected) connect(5.0);
521 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
522 return PvaClientMonitor::create(yyy,shared_from_this(),pvRequest);
525 PVStructurePtr PvaClientChannel::rpc(
526 PVStructurePtr
const & pvRequest,
527 PVStructurePtr
const & pvArgument)
531 return rpc->request(pvArgument);
534 PVStructurePtr PvaClientChannel::rpc(
535 PVStructurePtr
const & pvArgument)
538 return rpc->request(pvArgument);
543 if(connectState!=connected) connect(5.0);
545 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
546 return PvaClientRPC::create(yyy,channel);
549 PvaClientRPCPtr PvaClientChannel::createRPC(PVStructurePtr
const & pvRequest)
551 if(connectState!=connected) connect(5.0);
553 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
554 return PvaClientRPC::create(yyy,channel,pvRequest);
557 void PvaClientChannel::showCache()
559 if(pvaClientGetCache->cacheSize()>=1) {
560 cout <<
" pvaClientGet cache" << endl;
561 pvaClientGetCache->showCache();
563 cout <<
" pvaClientGet cache is empty\n";
565 if(pvaClientPutCache->cacheSize()>=1) {
566 cout <<
" pvaClientPut cache" << endl;
567 pvaClientPutCache->showCache();
569 cout <<
" pvaClientPut cache is empty\n";
573 size_t PvaClientChannel::cacheSize()
575 return pvaClientGetCache->cacheSize() + pvaClientPutCache->cacheSize();
std::tr1::shared_ptr< PvaClient > PvaClientPtr
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
std::tr1::shared_ptr< PvaClientPut > PvaClientPutPtr
std::tr1::shared_ptr< PvaClientMonitorRequester > PvaClientMonitorRequesterPtr
std::tr1::shared_ptr< PvaClientGet > PvaClientGetPtr
std::tr1::shared_ptr< PvaClientRPC > PvaClientRPCPtr
std::tr1::shared_ptr< PvaClientChannelStateChangeRequester > PvaClientChannelStateChangeRequesterPtr
std::tr1::shared_ptr< PvaClientProcess > PvaClientProcessPtr
std::tr1::shared_ptr< PvaClientPutGet > PvaClientPutGetPtr
std::tr1::shared_ptr< PvaClientMonitor > PvaClientMonitorPtr
std::tr1::shared_ptr< PvaClientPutData > PvaClientPutDataPtr