registry/service.h
Go to the documentation of this file.
00001 /* 00002 * Copyright 2006-2009 Savarese Software Research Corporation 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * https://www.savarese.com/software/ApacheLicense-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00022 #ifndef __SSRC_WSPR_REGISTRY_SERVICE_H 00023 #define __SSRC_WSPR_REGISTRY_SERVICE_H 00024 00025 #include <ssrc/wispers/index/IndexService.h> 00026 00027 __BEGIN_NS_SSRC_WSPR_REGISTRY 00028 00029 using NS_SSRC_SPREAD::MembershipInfo; 00030 using namespace NS_SSRC_WSPR_INDEX; 00031 00032 // TODO: move this into utility package or into ssrcspread 00033 int group_index(const NS_SSRC_SPREAD::GroupList & groups, 00034 const string & group); 00035 00039 class Registry : 00040 public IndexService<service_map, IndexScheme, 00041 NS_SSRC_WISP_PROTOCOL::GroupMembershipEnable> 00042 { 00043 friend class NS_SSRC_WISP_SERVICE::ServiceProtocolProcessor<packing_traits>; 00044 typedef IndexService<service_map, IndexScheme, GroupMembership> super; 00045 00046 WISP_IMPORT(NS_SSRC_WSPR_REGISTRY, MessageReregister); 00047 WISP_IMPORT(NS_SSRC_WSPR_REGISTRY, CallReregister); 00048 00049 bool _is_leader; 00050 string _leader_name; 00051 00052 void request_registrations(const string & registry, 00053 const bool self_discard = true); 00054 00055 void process_request(const MessageRegister & msg, const MessageInfo &) { 00056 register_service(msg.service_name, msg.service_types.begin(), 00057 msg.service_types.end()); 00058 } 00059 void process_request(const MessageReregister & msg, const MessageInfo &) { 00060 reregister_service(msg.service_name, msg.service_types.begin(), 00061 msg.service_types.end()); 00062 } 00063 00064 void process_request(const MessageUnregister & msg, const MessageInfo &){ 00065 unregister_service(msg.service_name, msg.service_types.begin(), 00066 msg.service_types.end()); 00067 } 00068 00069 void process_request(const MessageQueryByName & msg, 00070 const MessageInfo & msginfo) 00071 { 00072 if(is_leader() || group_index(msginfo.groups, name()) >= 0) 00073 process_query<ByName, CallQueryResult>(msg, msginfo); 00074 } 00075 00076 void process_request(const MessageQueryByType & msg, 00077 const MessageInfo & msginfo) 00078 { 00079 if(is_leader() || group_index(msginfo.groups, name()) >= 0) 00080 process_query<ByType, CallQueryResult>(msg, msginfo); 00081 } 00082 00083 void process_request(const MessageQueryAll & msg, 00084 const MessageInfo & msginfo) 00085 { 00086 if(is_leader() || group_index(msginfo.groups, name()) >= 0) { 00087 _caller.reply<CallQueryResult>(Message::FIFOSelfDiscard, msginfo.sender(), 00088 msginfo.token(), _index); 00089 } 00090 } 00091 00092 virtual void process_membership_message(const MessageInfo & msginfo, 00093 const MembershipInfo & meminfo); 00094 00095 virtual void transition(State state); 00096 00097 public: 00098 00102 explicit Registry(super::caller_type & caller) : 00103 super(caller), _is_leader(false), _leader_name() 00104 { 00105 add_service_type(protocol::service_type_registry()); 00106 00107 WISP_SERVICE_REQUEST(MessageRegister); 00108 WISP_SERVICE_REQUEST(MessageReregister); 00109 WISP_SERVICE_REQUEST(MessageUnregister); 00110 WISP_SERVICE_REQUEST(MessageQueryByName); 00111 WISP_SERVICE_REQUEST(MessageQueryByType); 00112 WISP_SERVICE_REQUEST(MessageQueryAll); 00113 } 00114 00115 virtual ~Registry() { } 00116 00120 bool is_leader() { 00121 return _is_leader; 00122 } 00123 00127 string leader_name() { 00128 return _leader_name; 00129 } 00130 00134 void service_join(const string & service_name) { 00135 if(count<ByName>(service_name) == 0) 00136 insert<ByName>(RegistryEntry(service_name, 00137 protocol::service_type_unknown())); 00138 } 00139 00143 void service_leave(const string & service_name) { 00144 erase<ByName>(service_name); 00145 } 00146 00150 template<typename InputIterator> 00151 void register_service(const string & service_name, 00152 InputIterator service_type, 00153 const InputIterator & end_of_range) 00154 { 00155 while(service_type != end_of_range) { 00156 insert<ByName>(RegistryEntry(service_name, *service_type)); 00157 ++service_type; 00158 } 00159 00160 // Remove unknown type. 00161 index_by_composite & index = get_index<ByComposite>(); 00162 index_by_composite::iterator it = 00163 index.find(boost::make_tuple(service_name, 00164 protocol::service_type_unknown())); 00165 00166 if(it != index.end()) 00167 index.erase(it); 00168 } 00169 00173 template<typename InputIterator> 00174 void reregister_service(const string & service_name, 00175 InputIterator service_type, 00176 const InputIterator & end_of_range) 00177 { 00178 get_index<ByName>().erase(service_name); 00179 register_service(service_name, service_type, end_of_range); 00180 } 00181 00185 template<typename InputIterator> 00186 void unregister_service(const string & service_name, 00187 InputIterator service_type, 00188 const InputIterator & end_of_range) 00189 { 00190 index_by_composite & index = get_index<ByComposite>(); 00191 index_by_composite::iterator it; 00192 00193 while(service_type != end_of_range) { 00194 it = index.find(boost::make_tuple(service_name, *service_type)); 00195 if(it != index.end()) 00196 index.erase(it); 00197 ++service_type; 00198 } 00199 00200 // Add unknown type entry if every service_name entry has been removed. 00201 if(count<ByName>(service_name) == 0) 00202 insert<ByName>(RegistryEntry(service_name, 00203 protocol::service_type_unknown())); 00204 } 00205 00206 }; 00207 00208 __END_NS_SSRC_WSPR_REGISTRY 00209 00210 #endif
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.