Branch data Line data Source code
1 : : /*
2 : : * Copyright 2006-2009 Savarese Software Research Corporation
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at
7 : : *
8 : : * https://www.savarese.com/software/ApacheLicense-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : /**
18 : : * @file
19 : : * This header defines the Registry class.
20 : : */
21 : :
22 : : #ifndef __SSRC_WSPR_REGISTRY_SERVICE_H
23 : : #define __SSRC_WSPR_REGISTRY_SERVICE_H
24 : :
25 : : #include <ssrc/wispers/index/IndexService.h>
26 : :
27 : : __BEGIN_NS_SSRC_WSPR_REGISTRY
28 : :
29 : : using NS_SSRC_SPREAD::MembershipInfo;
30 : : using namespace NS_SSRC_WSPR_INDEX;
31 : :
32 : : // TODO: move this into utility package or into ssrcspread
33 : : int group_index(const NS_SSRC_SPREAD::GroupList & groups,
34 : : const string & group);
35 : :
36 : : /**
37 : : *
38 : : */
39 : : class Registry :
40 : : public IndexService<service_map, IndexScheme,
41 : : NS_SSRC_WISP_PROTOCOL::GroupMembershipEnable>
42 : : {
43 : : friend class NS_SSRC_WISP_SERVICE::ServiceProtocolProcessor<packing_traits>;
44 : : typedef IndexService<service_map, IndexScheme, GroupMembership> super;
45 : :
46 : : WISP_IMPORT(NS_SSRC_WSPR_REGISTRY, MessageReregister);
47 : : WISP_IMPORT(NS_SSRC_WSPR_REGISTRY, CallReregister);
48 : :
49 : : bool _is_leader;
50 : : string _leader_name;
51 : :
52 : : void request_registrations(const string & registry,
53 : : const bool self_discard = true);
54 : :
55 : 1 : void process_request(const MessageRegister & msg, const MessageInfo &) {
56 : 1 : register_service(msg.service_name, msg.service_types.begin(),
57 : 2 : msg.service_types.end());
58 : 1 : }
59 : 2 : void process_request(const MessageReregister & msg, const MessageInfo &) {
60 : 2 : reregister_service(msg.service_name, msg.service_types.begin(),
61 : 4 : msg.service_types.end());
62 : 2 : }
63 : :
64 : 1 : void process_request(const MessageUnregister & msg, const MessageInfo &){
65 : 1 : unregister_service(msg.service_name, msg.service_types.begin(),
66 : 2 : msg.service_types.end());
67 : 1 : }
68 : :
69 : 3 : void process_request(const MessageQueryByName & msg,
70 : : const MessageInfo & msginfo)
71 : : {
72 [ - + # # : 3 : if(is_leader() || group_index(msginfo.groups, name()) >= 0)
# # # # -
+ + - #
# ]
73 : 3 : process_query<ByName, CallQueryResult>(msg, msginfo);
74 : 3 : }
75 : :
76 : 1 : void process_request(const MessageQueryByType & msg,
77 : : const MessageInfo & msginfo)
78 : : {
79 [ - + # # : 1 : if(is_leader() || group_index(msginfo.groups, name()) >= 0)
# # # # -
+ + - #
# ]
80 : 1 : process_query<ByType, CallQueryResult>(msg, msginfo);
81 : 1 : }
82 : :
83 : 1 : void process_request(const MessageQueryAll & msg,
84 : : const MessageInfo & msginfo)
85 : : {
86 [ - + # # : 1 : if(is_leader() || group_index(msginfo.groups, name()) >= 0) {
# # # # -
+ + - #
# ]
87 : 1 : _caller.reply<CallQueryResult>(Message::FIFOSelfDiscard, msginfo.sender(),
88 : 2 : msginfo.token(), _index);
89 : : }
90 : 1 : }
91 : :
92 : : virtual void process_membership_message(const MessageInfo & msginfo,
93 : : const MembershipInfo & meminfo);
94 : :
95 : : virtual void transition(State state);
96 : :
97 : : public:
98 : :
99 : : /**
100 : : *
101 : : */
102 : 6 : explicit Registry(super::caller_type & caller) :
103 [ + - ]: 6 : super(caller), _is_leader(false), _leader_name()
104 : : {
105 [ + - + - : 6 : add_service_type(protocol::service_type_registry());
+ - ]
106 : :
107 [ + - ]: 6 : WISP_SERVICE_REQUEST(MessageRegister);
108 [ + - ]: 6 : WISP_SERVICE_REQUEST(MessageReregister);
109 [ + - ]: 6 : WISP_SERVICE_REQUEST(MessageUnregister);
110 [ + - ]: 6 : WISP_SERVICE_REQUEST(MessageQueryByName);
111 [ + - ]: 6 : WISP_SERVICE_REQUEST(MessageQueryByType);
112 [ + - ]: 6 : WISP_SERVICE_REQUEST(MessageQueryAll);
113 : 6 : }
114 : :
115 [ + - - + ]: 6 : virtual ~Registry() { }
116 : :
117 : : /**
118 : : *
119 : : */
120 : 6 : bool is_leader() {
121 : 6 : return _is_leader;
122 : : }
123 : :
124 : : /**
125 : : *
126 : : */
127 : : string leader_name() {
128 : : return _leader_name;
129 : : }
130 : :
131 : : /**
132 : : *
133 : : */
134 : 5 : void service_join(const string & service_name) {
135 [ + + ]: 5 : if(count<ByName>(service_name) == 0)
136 : : insert<ByName>(RegistryEntry(service_name,
137 [ + - + - : 4 : protocol::service_type_unknown()));
+ - ]
138 : 5 : }
139 : :
140 : : /**
141 : : *
142 : : */
143 : 2 : void service_leave(const string & service_name) {
144 : 2 : erase<ByName>(service_name);
145 : 2 : }
146 : :
147 : : /**
148 : : *
149 : : */
150 : : template<typename InputIterator>
151 : 5 : void register_service(const string & service_name,
152 : : InputIterator service_type,
153 : : const InputIterator & end_of_range)
154 : : {
155 [ + + + + : 21 : while(service_type != end_of_range) {
+ + ]
156 [ + - + - : 11 : insert<ByName>(RegistryEntry(service_name, *service_type));
+ - ]
157 : 11 : ++service_type;
158 : : }
159 : :
160 : : // Remove unknown type.
161 : 5 : index_by_composite & index = get_index<ByComposite>();
162 : : index_by_composite::iterator it =
163 : : index.find(boost::make_tuple(service_name,
164 [ + - + - : 5 : protocol::service_type_unknown()));
+ - + - +
- + - + -
+ - + - ]
165 : :
166 [ - + - + : 5 : if(it != index.end())
+ + ]
167 : 1 : index.erase(it);
168 : 5 : }
169 : :
170 : : /**
171 : : *
172 : : */
173 : : template<typename InputIterator>
174 : 2 : void reregister_service(const string & service_name,
175 : : InputIterator service_type,
176 : : const InputIterator & end_of_range)
177 : : {
178 : 2 : get_index<ByName>().erase(service_name);
179 : 2 : register_service(service_name, service_type, end_of_range);
180 : 2 : }
181 : :
182 : : /**
183 : : *
184 : : */
185 : : template<typename InputIterator>
186 : 2 : void unregister_service(const string & service_name,
187 : : InputIterator service_type,
188 : : const InputIterator & end_of_range)
189 : : {
190 : 2 : index_by_composite & index = get_index<ByComposite>();
191 : 2 : index_by_composite::iterator it;
192 : :
193 [ + + + + ]: 7 : while(service_type != end_of_range) {
194 [ + - + - ]: 3 : it = index.find(boost::make_tuple(service_name, *service_type));
195 [ + - + - ]: 3 : if(it != index.end())
196 : 3 : index.erase(it);
197 : 3 : ++service_type;
198 : : }
199 : :
200 : : // Add unknown type entry if every service_name entry has been removed.
201 [ - + + - ]: 2 : if(count<ByName>(service_name) == 0)
202 [ # # # # : 1 : insert<ByName>(RegistryEntry(service_name,
# # + - +
- + - ]
203 : : protocol::service_type_unknown()));
204 : 2 : }
205 : :
206 : : };
207 : :
208 : : __END_NS_SSRC_WSPR_REGISTRY
209 : :
210 : : #endif
|