Savarese Software Research Corporation
group_session/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_GROUP_SESSION_SERVICE_H
00023 #define __SSRC_WSPR_GROUP_SESSION_SERVICE_H
00024 
00025 #include <ssrc/wispers/service/service.h>
00026 #include <ssrc/wispers/session/protocol.h>
00027 #include <ssrc/wispers/group_session/GroupSessionDatabase.h>
00028 #include <ssrc/wispers/group_session/protocol.h>
00029 #include <ssrc/wispers/group_session/GroupSessionOptions.h>
00030 #include <ssrc/wispers/utility/Random.h>
00031 
00032 __BEGIN_NS_SSRC_WSPR_GROUP_SESSION
00033 
00034 using NS_SSRC_SPREAD::Message;
00035 using NS_SSRC_WISP_PROTOCOL::MessageInfo;
00036 using NS_SSRC_WSPR_SERVICE::EventInfo;
00037 using NS_SSRC_WSPR_SERVICE::timeout_ptr;
00038 using NS_SSRC_WSPR_SESSION::SessionProtocol;
00039 using NS_SSRC_WSPR_SERVICE::ServiceProtocolProcessor;
00040 using NS_SSRC_WSPR_UTILITY::random_engine;
00041 using NS_SSRC_WSPR_UTILITY::Random;
00042 
00050 class GroupSessionService : public ServiceProtocolProcessor {
00051   friend class NS_SSRC_WISP_SERVICE::ServiceProtocolProcessor<packing_traits>;
00052   typedef ServiceProtocolProcessor super;
00053 
00054 protected:
00055   typedef GroupSessionProtocol protocol_traits;
00056 
00057   WISP_IMPORT(protocol_traits, MessageCreateGroupSession);
00058   WISP_IMPORT(protocol_traits, MessageEndGroupSession);
00059   WISP_IMPORT(protocol_traits, MessageExpireGroupSession);
00060   WISP_IMPORT(protocol_traits, MessageRelayEvent);
00061   WISP_IMPORT(protocol_traits, MessageRelayEventSelfDiscard);
00062   WISP_IMPORT(protocol_traits, MessageRelayEvents);
00063   WISP_IMPORT(protocol_traits, MessageRelayEventsSelfDiscard);
00064   WISP_IMPORT(protocol_traits, MessageFindGroupSessions);
00065   WISP_IMPORT(protocol_traits, MessageFindGroupSessionsResult);
00066   WISP_IMPORT(protocol_traits, MessageFindGroupSessionsForMember);
00067   WISP_IMPORT(protocol_traits, MessageReturnGroupSessionsForMember);
00068   WISP_IMPORT(protocol_traits, MessageFindGroupSessionsByType);
00069   WISP_IMPORT(protocol_traits, MessageReturnGroupSessionsByType);
00070   WISP_IMPORT(protocol_traits, MessageCreateReservation);
00071   WISP_IMPORT(protocol_traits, MessageCancelReservation);
00072 
00073   WISP_IMPORT(protocol_traits, MessageFindMembers);
00074   WISP_IMPORT(protocol_traits, MessageFindMembersResult);
00075   WISP_IMPORT(protocol_traits, MessageAddMembers);
00076   WISP_IMPORT(protocol_traits, MessageRemoveMembers);
00077   WISP_IMPORT(protocol_traits, MessageAddMember);
00078   WISP_IMPORT(protocol_traits, MessageRemoveMember);
00079 
00080   WISP_IMPORT(SessionProtocol, MessageExpireSession);
00081   WISP_IMPORT(SessionProtocol, MessageLoginSession);
00082 
00083   WISP_IMPORT(protocol_traits, CallStartGroupSession);
00084   WISP_IMPORT(protocol_traits, CallExpireGroupSession);
00085   WISP_IMPORT(protocol_traits, CallReturnGroupSessionsForMember);
00086   WISP_IMPORT(protocol_traits, CallReturnGroupSessionsByType);
00087   WISP_IMPORT(protocol_traits, CallFindGroupSessionsResult);
00088   WISP_IMPORT(protocol_traits, CallFindMembersResult);
00089   WISP_IMPORT(protocol_traits, CallAddMemberConfirm);
00090   WISP_IMPORT(protocol_traits, CallRemoveMemberConfirm);
00091 
00092   static const string EventGroupExpireGroupSession;
00093 
00094   const unsigned int _protocol_id;
00095   const unsigned int _partition_id;
00096   const unsigned int _num_partitions;
00097   const unsigned int _ids_per_expiration_message;
00098   boost::scoped_ptr<GroupSessionDatabase> _database;
00099   const gsid_type _gsid_min, _gsid_max;
00100   Random<gsid_type> _random;
00101   TimeValue _gs_poll_interval;
00102   timeout_ptr _gs_poll_timeout;
00103   unsigned int _session_count, _reservation_count;
00104   const std::string _gs_name;
00105 
00106   gsid_type generate_gsid() {
00107     return _random();
00108   }
00109 
00110   void recount_sessions() SSRC_DECL_THROW(DatabaseException) {
00111     _session_count = _database->count_sessions();
00112     _reservation_count = _database->count_reservations();
00113   }
00114 
00115   virtual void start_group_session(const GroupSession & session,
00116                                    ByteBuffer & payload)
00117   {
00118     _caller.sendp<CallStartGroupSession>(session.group, _gs_name, session);
00119   }
00120 
00121   void process_request(MessageCreateGroupSession & msg,
00122                        const MessageInfo &);
00123 
00124 
00125   virtual void end_group_session(const gsid_type gsid) {
00126     DatabaseTransaction transaction(*_database);
00127     if(_database->group_session_ops.erase(gsid) == 1)
00128       --_session_count;
00129     transaction.end();
00130     
00131   }
00132 
00133   void process_request(const MessageEndGroupSession & msg,
00134                        const MessageInfo &)
00135   {
00136     end_group_session(msg.gsid);
00137   }
00138 
00139   virtual bool insert_reservation(const Reservation & reservation,
00140                                   ByteBuffer & payload)
00141     SSRC_DECL_THROW(DatabaseException)
00142   {
00143     if(_database->reservation_ops.insert(reservation)) {
00144       ++_reservation_count;
00145       return true;
00146     }
00147     return false;
00148   }
00149 
00150   void process_request(MessageCreateReservation & msg,
00151                        const MessageInfo &);
00152 
00153   virtual void confirm_reservation_activation(const GroupSession & session) {
00154     _caller.sendp<CallStartGroupSession>(session.group, _gs_name, session);
00155   }
00156 
00157 
00158   template<typename reservation_type>
00159   void activate_reservation(const reservation_type & reservation,
00160                             const string & session_name,
00161                             const member_container & additional_participants)
00162   {
00163     try {
00164       const sec_type created(TimeValue::now_seconds());
00165       const GroupSession session(reservation.gsid,
00166                                  created,
00167                                  created + reservation.gs_lifetime,
00168                                  reservation.type,
00169                                  reservation.group,
00170                                  (session_name.empty() ?
00171                                   reservation.name :
00172                                   session_name),
00173                                  reservation.max_observers);
00174       DatabaseTransaction transaction(*_database);
00175 
00176       if(_database->group_session_ops.insert(session)) {
00177         ++_session_count;
00178         _database->activate_reservation_participants(session.gsid);
00179 
00180         if(additional_participants.size() > 0)
00181           _database->participant_ops.insert(additional_participants.begin(),
00182                                             additional_participants.end());
00183 
00184         if(_database->remove_reservation(session.gsid,
00185                                          reservation.creator_uid) == 1)
00186         {
00187           --_reservation_count;
00188         }
00189       }
00190 
00191       transaction.end();
00192 
00193       confirm_reservation_activation(session);
00194     } catch(const DatabaseException & de) {
00195       // TODO: log.
00196       recount_sessions();
00197     }
00198   }
00199 
00200   void process_request(const MessageFindGroupSessionsByType & msg,
00201                        const MessageInfo & msginfo);
00202 
00203 
00204   void process_request(const MessageFindGroupSessions & msg,
00205                        const MessageInfo & msginfo);
00206 
00207   void process_request(const MessageFindMembers & msg,
00208                        const MessageInfo & msginfo);
00209 
00210   void process_request(const MessageAddMembers & msg,
00211                        const MessageInfo &);
00212 
00213   void process_request(const MessageRemoveMembers & msg,
00214                        const MessageInfo &);
00215 
00216   void process_request(const MessageAddMember & msg,
00217                        const MessageInfo & msginfo);
00218 
00219   void process_request(const MessageRemoveMember & msg,
00220                        const MessageInfo & msginfo);
00221 
00222   virtual unsigned int cancel_reservation(const gsid_type gsid,
00223                                           const uid_type requestor,
00224                                           const MessageInfo &);
00225 
00226   void process_request(const MessageCancelReservation & msg,
00227                        const MessageInfo & msginfo)
00228   {
00229     cancel_reservation(msg.gsid, msg.requestor, msginfo);
00230   }
00231 
00232   void process_request(const MessageFindGroupSessionsForMember & msg,
00233                        const MessageInfo & msginfo);
00234 
00235   void process_request(const MessageRelayEvent & msg, const MessageInfo &);
00236 
00237   void process_request(const MessageRelayEventSelfDiscard & msg,
00238                        const MessageInfo &);
00239 
00240   void process_request(MessageRelayEvents & msg, const MessageInfo &);
00241 
00242   void process_request(MessageRelayEventsSelfDiscard & msg,
00243                        const MessageInfo &);
00244 
00245   void process_request(const MessageExpireSession & msg,
00246                        const MessageInfo &);
00247 
00248   void process_request(const MessageLoginSession & msg,
00249                        const MessageInfo &);
00250 
00251   virtual void transition(State state);
00252 
00253 public:
00254 
00255   GroupSessionService(super::caller_type & caller,
00256                       const wisp_message_protocol protocol,
00257                       GroupSessionDatabase *db, 
00258                       const GroupSessionInitializer & initializer)
00259     SSRC_DECL_THROW(DatabaseException, std::invalid_argument);
00260 
00261   virtual ~GroupSessionService() { }
00262 
00263   virtual unsigned int check_for_expirations(const sec_type now);
00264 
00265 private:
00266 
00267   void send_expirations(const gsid_container & gsids);
00268 
00269   void _check_for_expirations(const EventInfo & info) {
00270     check_for_expirations(TimeValue::now_seconds());
00271   }
00272 };
00273 
00274 __END_NS_SSRC_WSPR_GROUP_SESSION
00275 
00276 #endif

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