root/trunk/whisperlib/net/rpc/lib/server/rpc_services_manager.cc

Revision 7, 5.0 kB (checked in by whispercastorg, 2 years ago)

version 0.2.0

Line 
1 // Copyright (c) 2009, Whispersoft s.r.l.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Whispersoft s.r.l. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Author: Cosmin Tudorache
31
32 #include "net/rpc/lib/server/rpc_services_manager.h"
33 #include "net/rpc/lib/types/rpc_void.h"
34
35 namespace rpc {
36
37 rpc::ServicesManager::ServicesManager()
38     : services_() {
39 }
40
41 rpc::ServicesManager::~ServicesManager() {
42   CHECK(services_.empty());
43 }
44
45 string rpc::ServicesManager::StrListServices(const string& glue) const {
46   // compute result string length
47   uint32 result_len = services_.empty() ? 0
48                       : ((services_.size() - 1) * glue.length());
49   for ( ServicesMap::const_iterator it = services_.begin();
50         it != services_.end(); ++it ) {
51     rpc::ServiceInvoker& invoker = *it->second;
52     result_len += invoker.GetName().length();
53   }
54
55   // allocate result
56   string result;
57   result.reserve(result_len + 1);
58
59   // build result
60   for ( ServicesMap::const_iterator it = services_.begin();
61         it != services_.end(); ) {
62     rpc::ServiceInvoker& invoker = *it->second;
63     result.append(invoker.GetName());
64     ++it;
65     if ( it != services_.end() ) {
66       result.append(glue);
67     }
68   }
69
70   return result;
71 }
72 rpc::ServiceInvoker* rpc::ServicesManager::FindService(
73     const string& serviceName) {
74   ServicesMap::iterator it = services_.find(serviceName);
75   if ( it == services_.end() ) {
76     return NULL;
77   }
78   return it->second;
79 }
80
81 bool rpc::ServicesManager::RegisterService(rpc::ServiceInvoker& service) {
82   // try to insert the pair [serviceName, &service] the services_ map
83   //
84   pair<ServicesMap::iterator, bool>
85       p  = services_.insert(make_pair(service.GetName(), &service));
86   if ( p.second == false ) {
87     // The Key already exists in the map. The Value has NOT been replaced.
88
89     // Service name already registered.
90     //
91     const rpc::ServiceInvoker* existingService = p.first->second;
92     CHECK(existingService);
93     LOG_ERROR << "ServiceName: " << service.GetName()
94               << " already registered with service: " << (*existingService);
95     return false;
96   }
97
98   // the pair [serviceName, &service] was successfully put into map
99   //
100   // debug purpose: mark the service as registered so it cannot be
101   //                silently deleted
102   service.SetRegistered(true);
103
104   LOG_INFO << "Registered: " << service;
105   return true;
106 }
107
108 void rpc::ServicesManager::UnregisterService(const string& serviceName) {
109   ServicesMap::iterator it = services_.find(serviceName);
110   if ( it == services_.end() ) {
111     LOG_ERROR << "Service " << serviceName
112               << " not registered. Cannot unregister.";
113     return;
114   }
115
116   // check service sanity
117   //
118   rpc::ServiceInvoker* service = it->second;
119   CHECK_NOT_NULL(service);
120   CHECK_EQ(serviceName, service->GetName());
121
122   // remove the service
123   //
124   services_.erase(it);
125
126   // debug purpose: mark the service as unregistered.
127   //
128   service->SetRegistered(false);
129   LOG_INFO << "Unregistered: " << (*service);
130 }
131
132 void rpc::ServicesManager::UnregisterService(
133     const rpc::ServiceInvoker& service) {
134   UnregisterService(service.GetName());
135 }
136
137 bool rpc::ServicesManager::Call(rpc::Query* q) {
138   LOG_INFO << "Call:"
139            << " service=" << q->service()
140            << " method=" << q->method();
141   rpc::ServiceInvoker* service = FindService(q->service());
142   if ( !service ) {
143     LOG_WARNING << "Cannot find service: " << q->service();
144     q->Complete(RPC_SERVICE_UNAVAIL);
145     return true;
146   }
147   return service->Call(q);
148 }
149
150 string rpc::ServicesManager::ToString() const {
151   ostringstream oss;
152   oss << "rpc::ServicesManager: #" << services_.size()
153       << " services: {" << StrListServices(", ") << "}";
154   return oss.str();
155 }
156 }
Note: See TracBrowser for help on using the browser.