Savarese Software Research Corporation
registry/service.cc
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 
00017 #include <set>
00018 
00019 #include <ssrc/wispers/registry/service.h>
00020 
00021 __BEGIN_NS_SSRC_WSPR_REGISTRY
00022 
00023 using NS_SSRC_WSPR_SERVICE::ServiceProtocol;
00024 
00025 // TODO: move this into utility package or into ssrcspread
00026 int group_index(const NS_SSRC_SPREAD::GroupList & groups,
00027                 const string & group)
00028 {
00029   int index(groups.size());
00030 
00031   while(index-- > 0) {
00032     if(groups[index] == group)
00033       return index;
00034   }
00035 
00036   return index;
00037 }
00038 
00042 void Registry::request_registrations(const string & registry,
00043                                      const bool self_discard)
00044 {
00045   Message::Service service_type =
00046     (self_discard ? Message::FIFO : Message::FIFOSelfDiscard);
00047 
00048   _caller.send<ServiceProtocol::CallReregister>
00049     (service_type, ServiceProtocol::service_group(), registry);
00050 }
00051 
00055 void Registry::process_membership_message(const MessageInfo & msginfo,
00056                                           const MembershipInfo & meminfo)
00057 {
00058   string sender(msginfo.sender());
00059 
00060   if(sender == ServiceProtocol::service_group()) {
00061     if(meminfo.caused_by_join()) {
00062       string changed(meminfo.changed_member());
00063 
00064       if(name() == changed) {
00065         // TODO: Move to separate method.
00066         // Register all existing services (includes us) as unknown.
00067         const unsigned int count_groups = _caller.mbox().count_groups();
00068         for(unsigned int i = 0; i < count_groups; ++i)
00069           service_join(msginfo.groups[i]);
00070 
00071         request_registrations(name());
00072       } else
00073         service_join(changed);
00074     } else if(meminfo.caused_by_leave() || meminfo.caused_by_disconnect())
00075       service_leave(meminfo.changed_member());
00076     else if(meminfo.caused_by_network()) {
00077       // Remove all service entries that aren't in new group.
00078       typedef boost::multi_index_container<string> group_set;
00079       group_set group;
00080       int i = _caller.mbox().count_groups();
00081 
00082       while(i-- > 0)
00083         group.insert(msginfo.groups[i]);
00084 
00085       group_set::iterator group_end(group.end());
00086       index_by_name::iterator it(begin<ByName>());
00087       index_by_name::iterator end(end<ByName>());
00088 
00089       while(it != end) {
00090         if(group.find(it->service_name) == group_end)
00091           get_index<ByName>().erase(it);
00092         ++it;
00093       }
00094     }
00095   } else if(sender == service_group_registry()) {
00096     if(meminfo.is_regular_membership()) {
00097       if(_caller.mbox().count_groups() > 0)
00098         _leader_name = msginfo.groups[0];
00099       else
00100         _leader_name.clear();
00101 
00102       _is_leader = (_leader_name == name());
00103 
00104       // Request reregistrations to go to registry.
00105       if(meminfo.caused_by_network() && _is_leader)
00106         request_registrations(service_group_registry(), false);
00107     }
00108   }
00109 }
00110 
00114 void Registry::transition(State state) {
00115   switch(state) {
00116   case Starting:
00117     _caller.join(service_group_registry());
00118     state = Started;
00119     break;
00120   case Stopping:
00121     _caller.leave(service_group_registry());
00122     break;
00123   default:
00124     break;
00125   }
00126 
00127   // Transition at end so we've joined registry group before
00128   // super::transition registers us.
00129   super::transition(state);
00130 }
00131 
00132 __END_NS_SSRC_WSPR_REGISTRY

Savarese Software Research Corporation
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.