group_session/protocol.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_GROUP_SESSION_PROTOCOL_H 00023 #define __SSRC_WSPR_GROUP_SESSION_PROTOCOL_H 00024 00025 #include <ssrc/wispers/protocol.h> 00026 #include <ssrc/wispers/utility/Properties.h> 00027 #include <ssrc/wispers/utility/ToString.h> 00028 #include <ssrc/wispers/group_session/types.h> 00029 00030 // Includes serialize function for std::pair. 00031 #include <boost/serialization/utility.hpp> 00032 00033 __BEGIN_NS_SSRC_WSPR_PROTOCOL 00034 00035 WSPR_DEFINE_PROTOCOL(GroupSession,group_session); 00036 00037 __END_NS_SSRC_WSPR_PROTOCOL 00038 00039 __BEGIN_NS_SSRC_WSPR_GROUP_SESSION 00040 00041 using NS_SSRC_WSPR::ByteBuffer; 00042 using NS_SSRC_WSPR_UTILITY::Properties; 00043 using NS_SSRC_WSPR_UTILITY::properties_ptr; 00044 using NS_SSRC_WSPR_UTILITY::ToString; 00045 using NS_SSRC_WISP_PROTOCOL::wisp_message_protocol; 00046 00047 typedef std::vector<gsid_type> gsid_container; 00048 typedef std::vector<uid_type> uid_container; 00049 typedef std::vector<GroupSession> group_session_container; 00050 typedef std::vector<Reservation> reservation_container; 00051 typedef std::vector<Member> member_container; 00052 00053 struct GroupSessionProtocol : 00054 public protocol::ServiceProtocol<protocol::GroupSession> 00055 { 00056 typedef protocol::ServiceProtocol<protocol::GroupSession> super; 00057 00058 WISP_IMPORT(super, caller_type); 00059 00061 static const gsid_type GSIDMax = boost::integer_traits<gsid_type>::const_max; 00062 00064 static const gsid_type GSIDMin = boost::integer_traits<gsid_type>::const_min; 00065 00071 // Calculation is independent of whether gsid_type is signed or unsigned. 00072 // Protocol numbers start at 0, which is why we use 00073 // boost::integer_traits<wisp_message_protocol>::const_max without respect 00074 // to the distance to const_min. 00075 static const gsid_type GSIDSpace = 00076 (((boost::integer_traits<gsid_type>::const_max >> 2) + 1) 00077 - (boost::integer_traits<gsid_type>::const_min >> 2)) / 00078 ((boost::integer_traits<wisp_message_protocol>::const_max >> 2) + 1); 00079 00080 static string event_group_expire() { 00081 return WSPR_EVENT_GROUP("group_session", "expire"); 00082 } 00083 00084 enum { 00085 RelayEvent, 00086 RelayEventSelfDiscard, 00087 RelayEvents, 00088 RelayEventsSelfDiscard, 00089 CreateGroupSession, 00090 EndGroupSession, 00091 ExpireGroupSession, 00092 FindGroupSessions, 00093 FindGroupSessionsResult, 00094 FindGroupSessionsForMember, 00095 ReturnGroupSessionsForMember, 00096 FindGroupSessionsByType, 00097 ReturnGroupSessionsByType, 00098 CreateReservation, 00099 CancelReservation, 00100 StartGroupSession, 00101 FindMembers, 00102 FindMembersResult, 00103 AddMembers, 00104 RemoveMembers, 00105 AddMember, 00106 AddMemberConfirm, 00107 RemoveMember, 00108 RemoveMemberConfirm 00109 }; 00110 00111 enum { DefaultPayloadCapacity = NS_SSRC_SPREAD::Message::DefaultCapacity }; 00112 00113 enum MemberType { Participant, Observer }; 00114 00115 struct MessageCreateGroupSession : 00116 public protocol::MessageGroupSession<CreateGroupSession> 00117 { 00118 string session_name; 00119 string session_group; 00120 string session_type; 00121 sec_type lifetime; 00122 uid_container participants; 00123 unsigned int max_observers; 00124 ByteBuffer payload; 00125 00126 MessageCreateGroupSession() : payload(DefaultPayloadCapacity) { } 00127 00128 MessageCreateGroupSession(const string & session_name, 00129 const string & session_group, 00130 const string & session_type, 00131 const sec_type lifetime, 00132 const uid_container & participants, 00133 const unsigned int max_observers) : 00134 session_name(session_name), 00135 session_group(session_group), 00136 session_type(session_type), 00137 lifetime(lifetime), 00138 participants(participants), 00139 max_observers(max_observers), 00140 payload(DefaultPayloadCapacity) 00141 { } 00142 00143 template<class Archive> 00144 void serialize(Archive & ar, const unsigned int) { 00145 ar & session_name & session_group & session_type & lifetime 00146 & participants & max_observers & payload; 00147 } 00148 }; 00149 00150 struct MessageCreateReservation : 00151 public protocol::MessageGroupSession<CreateReservation> 00152 { 00153 string session_name; 00154 string session_group; 00155 string session_type; 00156 sec_type gs_lifetime; 00157 uid_type creator_uid; 00158 sec_type reservation_lifetime; 00159 unsigned int max_observers; 00160 ByteBuffer payload; 00161 00162 MessageCreateReservation() : payload(DefaultPayloadCapacity) { } 00163 00164 MessageCreateReservation(const string & session_name, 00165 const string & session_group, 00166 const string & session_type, 00167 const sec_type gs_lifetime, 00168 const uid_type creator_uid, 00169 const sec_type reservation_lifetime, 00170 const unsigned int max_observers) : 00171 session_name(session_name), 00172 session_group(session_group), 00173 session_type(session_type), 00174 gs_lifetime(gs_lifetime), 00175 creator_uid(creator_uid), 00176 reservation_lifetime(reservation_lifetime), 00177 max_observers(max_observers), 00178 payload(DefaultPayloadCapacity) 00179 { } 00180 00181 template<class Archive> 00182 void serialize(Archive & ar, const unsigned int) { 00183 ar & session_name & session_group & session_type & gs_lifetime 00184 & creator_uid & reservation_lifetime & max_observers & payload; 00185 } 00186 }; 00187 00188 WISP_PROTOCOL_MESSAGE(EndGroupSession, protocol::MessageGroupSession, 00189 ((gsid_type, gsid))); 00190 00191 WISP_PROTOCOL_MESSAGE(CancelReservation, protocol::MessageGroupSession, 00192 ((gsid_type, gsid))((uid_type, requestor))); 00193 00194 WISP_PROTOCOL_MESSAGE(StartGroupSession, 00195 protocol::MessageGroupSession, 00196 ((string, gs_name)) 00197 ((GroupSession, session))); 00198 00199 WISP_STRUCT(ExpirationNotification, 00200 ((gsid_type, gsid)) 00201 ((uid_container, uids))); 00202 typedef 00203 std::vector<ExpirationNotification> expiration_notification_container; 00207 WISP_PROTOCOL_MESSAGE(ExpireGroupSession, protocol::MessageGroupSession, 00208 ((expiration_notification_container, notifications))); 00209 00210 WISP_PROTOCOL_MESSAGE_WITH_INIT(RelayEvent, protocol::MessageGroupSession, 00211 ((gsid_type, gsid)) 00212 ((string, event_queue)) 00213 ((properties_ptr, event)), 00214 ((gsid_type())) 00215 ((string())) 00216 ((properties_ptr(new Properties)))); 00217 00218 WISP_PROTOCOL_MESSAGE_WITH_INIT(RelayEventSelfDiscard, 00219 protocol::MessageGroupSession, 00220 ((uid_type, source)) 00221 ((gsid_type, gsid)) 00222 ((string, event_queue)) 00223 ((properties_ptr, event)), 00224 ((uid_type())) 00225 ((gsid_type())) 00226 ((string())) 00227 ((properties_ptr(new Properties)))); 00228 00229 WISP_PROTOCOL_MESSAGE_WITH_INIT(RelayEvents, protocol::MessageGroupSession, 00230 ((gsid_type, gsid)) 00231 ((string, event_queue)) 00232 ((std::vector<Properties>, events)), 00233 ((gsid_type())) 00234 ((string())) 00235 ((std::vector<Properties>()))); 00236 00237 WISP_PROTOCOL_MESSAGE_WITH_INIT(RelayEventsSelfDiscard, 00238 protocol::MessageGroupSession, 00239 ((uid_type, source)) 00240 ((gsid_type, gsid)) 00241 ((string, event_queue)) 00242 ((std::vector<Properties>, events)), 00243 ((uid_type())) 00244 ((gsid_type())) 00245 ((string())) 00246 ((std::vector<Properties>()))); 00247 00248 WISP_PROTOCOL_MESSAGE(FindGroupSessions, protocol::MessageGroupSession, 00249 ((uid_type, requestor)) 00250 ((db_limit_type, limit)) 00251 ((db_offset_type, offset))); 00252 00253 WISP_PROTOCOL_MESSAGE(FindGroupSessionsResult, protocol::MessageGroupSession, 00254 ((uid_type, requestor)) 00255 ((unsigned int, total_sessions)) 00256 ((db_limit_type, limit)) 00257 ((db_offset_type, offset)) 00258 ((string, gs_name)) 00259 ((group_session_container, sessions))); 00260 00261 WISP_PROTOCOL_MESSAGE(FindGroupSessionsForMember, 00262 protocol::MessageGroupSession, 00263 ((uid_type, uid))); 00264 00265 WISP_PROTOCOL_MESSAGE(ReturnGroupSessionsForMember, 00266 protocol::MessageGroupSession, 00267 ((uid_type, uid)) 00268 ((string, gs_name)) 00269 ((group_session_container, participating)) 00270 ((group_session_container, observing)) 00271 ((reservation_container, awaiting))); 00272 00273 typedef std::vector<string> query_list; 00274 WISP_PROTOCOL_MESSAGE(FindGroupSessionsByType, protocol::MessageGroupSession, 00275 ((query_list, keys))); 00276 WISP_PROTOCOL_MESSAGE(ReturnGroupSessionsByType, 00277 protocol::MessageGroupSession, 00278 ((group_session_container, sessions))); 00279 00280 WISP_PROTOCOL_MESSAGE(FindMembers, 00281 protocol::MessageGroupSession, 00282 ((uid_type, requestor)) 00283 ((gsid_container, sessions))); 00284 00285 WISP_PROTOCOL_MESSAGE(FindMembersResult, 00286 protocol::MessageGroupSession, 00287 ((uid_type, requestor)) 00288 ((member_container, participants)) 00289 ((member_container, observers))); 00290 00291 WISP_PROTOCOL_MESSAGE(AddMembers, 00292 protocol::MessageGroupSession, 00293 ((member_container, participants)) 00294 ((member_container, observers))); 00295 00296 WISP_PROTOCOL_MESSAGE(RemoveMembers, 00297 protocol::MessageGroupSession, 00298 ((member_container, participants)) 00299 ((member_container, observers))); 00300 00301 WISP_PROTOCOL_MESSAGE(AddMember, 00302 protocol::MessageGroupSession, 00303 ((MemberType, member_type)) 00304 ((Member, member))); 00305 00306 enum AddMemberResultCode { 00307 AddMemberInternalError, 00308 AddMemberNonexistentGroupSession, 00309 AddMemberDuplicateEntry, 00310 AddMemberMaxObserversReached, 00311 AddMemberSuccess 00312 }; 00313 00314 WISP_PROTOCOL_MESSAGE(AddMemberConfirm, 00315 protocol::MessageGroupSession, 00316 ((AddMemberResultCode, result)) 00317 ((MemberType, member_type)) 00318 ((uid_type, uid)) 00319 ((string, gs_name)) 00320 ((GroupSession, session))); 00321 00322 WISP_PROTOCOL_MESSAGE(RemoveMember, 00323 protocol::MessageGroupSession, 00324 ((MemberType, member_type)) 00325 ((Member, member))); 00326 00327 WISP_PROTOCOL_MESSAGE(RemoveMemberConfirm, 00328 protocol::MessageGroupSession, 00329 ((MemberType, member_type)) 00330 ((Member, member)) 00331 ((string, gs_name)) 00332 ((GroupSession, session))); 00333 00334 WISP_ONE_WAY_CALL(caller_type, CreateGroupSession); 00335 WISP_ONE_WAY_CALL(caller_type, EndGroupSession); 00336 WISP_ONE_WAY_CALL(caller_type, ExpireGroupSession); 00337 WISP_ONE_WAY_CALL(caller_type, RelayEvent); 00338 WISP_ONE_WAY_CALL(caller_type, RelayEventSelfDiscard); 00339 WISP_ONE_WAY_CALL(caller_type, RelayEvents); 00340 WISP_ONE_WAY_CALL(caller_type, RelayEventsSelfDiscard); 00341 00342 WISP_ONE_WAY_CALL(caller_type, CreateReservation); 00343 WISP_ONE_WAY_CALL(caller_type, CancelReservation); 00344 WISP_ONE_WAY_CALL(caller_type, StartGroupSession); 00345 00346 WISP_TWO_WAY_CALL(caller_type, FindGroupSessionsForMember, 00347 ReturnGroupSessionsForMember); 00348 WISP_ONE_WAY_CALL(caller_type, ReturnGroupSessionsForMember); 00349 00350 WISP_TWO_WAY_CALL(caller_type, FindGroupSessionsByType, 00351 ReturnGroupSessionsByType); 00352 WISP_ONE_WAY_CALL(caller_type, ReturnGroupSessionsByType); 00353 00354 // Conceptually these are two-way calls, but we don't invoke them that way. 00355 WISP_ONE_WAY_CALL(caller_type, FindGroupSessions); 00356 WISP_ONE_WAY_CALL(caller_type, FindGroupSessionsResult); 00357 WISP_ONE_WAY_CALL(caller_type, FindMembers); 00358 WISP_ONE_WAY_CALL(caller_type, FindMembersResult); 00359 00360 00361 WISP_ONE_WAY_CALL(caller_type, AddMembers); 00362 WISP_ONE_WAY_CALL(caller_type, RemoveMembers); 00363 WISP_ONE_WAY_CALL(caller_type, AddMember); 00364 WISP_ONE_WAY_CALL(caller_type, AddMemberConfirm); 00365 WISP_ONE_WAY_CALL(caller_type, RemoveMember); 00366 WISP_ONE_WAY_CALL(caller_type, RemoveMemberConfirm); 00367 }; 00368 00378 template<typename session_type> 00379 inline void bind_group_session_properties(const session_type & session, 00380 Properties & node) 00381 { 00382 node.set(session.gsid, "gsid"); 00383 node.set(session.created, "created"); 00384 node.set(session.expires, "expires"); 00385 node.set(session.type, "type"); 00386 node.set(session.name, "name"); 00387 } 00388 00395 inline gsid_type gsid_min(const wisp_message_protocol protocol) { 00396 return 00397 (GroupSessionProtocol::GSIDMin + 00398 (static_cast<gsid_type>(protocol) * GroupSessionProtocol::GSIDSpace)); 00399 } 00400 00407 inline gsid_type gsid_max(const wisp_message_protocol protocol) { 00408 return 00409 ((GroupSessionProtocol::GSIDMin + 00410 (static_cast<gsid_type>(protocol) + 1) * GroupSessionProtocol::GSIDSpace) - 1); 00411 } 00412 00424 inline gsid_type gsid_min(const wisp_message_protocol protocol, 00425 const unsigned int partition_id, 00426 const unsigned int num_partitions) 00427 { 00428 const gsid_type min_gsid = gsid_min(protocol); 00429 const gsid_type space = GroupSessionProtocol::GSIDSpace / num_partitions; 00430 00431 return (min_gsid + space * partition_id); 00432 } 00433 00445 inline gsid_type gsid_max(const wisp_message_protocol protocol, 00446 const unsigned int partition_id, 00447 const unsigned int num_partitions) 00448 { 00449 // Spill over space rounding error to last partition. 00450 if(partition_id >= (num_partitions - 1)) 00451 return gsid_max(protocol); 00452 00453 return gsid_min(protocol, partition_id + 1, num_partitions) - 1; 00454 } 00455 00462 inline wisp_message_protocol gsid_to_protocol(const gsid_type gsid) { 00463 // Can't use basic algebra because of overflow. 00464 gsid_type result(gsid); 00465 00466 if(gsid < 0) 00467 result-=GroupSessionProtocol::GSIDMin; 00468 00469 result /= GroupSessionProtocol::GSIDSpace; 00470 00471 if(gsid >= 0) { 00472 const gsid_type midpoint = 00473 (boost::integer_traits<wisp_message_protocol>::const_min / -2); 00474 result+=midpoint; 00475 } 00476 00477 return static_cast<wisp_message_protocol>(result); 00478 } 00479 00488 inline 00489 unsigned int gsid_to_protocol_partition(gsid_type gsid, 00490 const unsigned int num_partitions) 00491 { 00492 const wisp_message_protocol protocol = gsid_to_protocol(gsid); 00493 const gsid_type space = GroupSessionProtocol::GSIDSpace / num_partitions; 00494 00495 gsid-=gsid_min(protocol); 00496 gsid /= space; 00497 00498 if(gsid >= num_partitions) 00499 gsid = num_partitions - 1; 00500 00501 return static_cast<unsigned int>(gsid); 00502 } 00503 00511 class GSToGroup { 00512 const string _gs_protocol_prefix; 00513 string _gs_group; 00514 ToString _string_cast; 00515 00516 public: 00517 00518 GSToGroup() : 00519 _gs_protocol_prefix("wspr.gs.protocol."), 00520 _gs_group(_gs_protocol_prefix), 00521 _string_cast() 00522 { } 00523 00524 const string & gs_protocol_group(const wisp_message_protocol protocol) { 00525 _gs_group.erase(_gs_protocol_prefix.size()); 00526 return _gs_group.append(_string_cast(protocol)); 00527 } 00528 00529 const string & 00530 gs_protocol_partition_group(const wisp_message_protocol protocol, 00531 const unsigned int partition_id) 00532 { 00533 _gs_group.erase(_gs_protocol_prefix.size()); 00534 _gs_group.append(_string_cast(protocol)).append("."); 00535 // Can't string together all of the appends because of undefined 00536 // execution order of _string_cast, which returns a reference and 00537 // can cause the protocol value to be used in each case. 00538 return _gs_group.append(_string_cast(partition_id)); 00539 } 00540 00541 const string & gsid_protocol_group(const gsid_type gsid) { 00542 return gs_protocol_group(gsid_to_protocol(gsid)); 00543 } 00544 }; 00545 00555 inline string gs_protocol_group(const wisp_message_protocol protocol) { 00556 GSToGroup gsid_to_group; 00557 return gsid_to_group.gs_protocol_group(protocol); 00558 } 00559 00571 inline 00572 string gs_protocol_partition_group(const wisp_message_protocol protocol, 00573 const unsigned int partition_id) 00574 { 00575 GSToGroup gsid_to_group; 00576 return gsid_to_group.gs_protocol_partition_group(protocol, partition_id); 00577 } 00578 00587 inline string gsid_protocol_group(const gsid_type gsid) { 00588 GSToGroup gsid_to_group; 00589 return gsid_to_group.gsid_protocol_group(gsid); 00590 } 00591 00592 __END_NS_SSRC_WSPR_GROUP_SESSION 00593 00594 #endif
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.