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_SESSION_SERVICE_H 00023 #define __SSRC_WSPR_SESSION_SERVICE_H 00024 00025 #include <ssrc/wispers/index/DictionaryService.h> 00026 #include <ssrc/wispers/session/protocol.h> 00027 #include <ssrc/wispers/utility/RandomId.h> 00028 00029 __BEGIN_NS_SSRC_WSPR_SESSION 00030 00031 using NS_SSRC_WSPR_SERVICE::timeout_ptr; 00032 using NS_SSRC_WSPR_UTILITY::RandomId; 00033 00034 struct SessionInitializer { 00035 unsigned int expirations_per_message; 00036 // These are in seconds. For best results, max_idle_time should be 00037 // an integer multiple of poll_interval. 00038 unsigned int poll_interval; 00039 unsigned int max_idle_time; 00040 std::string checkpoint_path; 00041 00042 SessionInitializer() : 00043 expirations_per_message(1024), poll_interval(300), max_idle_time(1800) 00044 { } 00045 }; 00046 00050 class Session : public DictionaryService<SessionProtocol> { 00051 public: 00052 WISP_IMPORT(SessionProtocol, MessageSingleQueryResult); 00053 WISP_IMPORT(SessionProtocol, MessageInsert); 00054 WISP_IMPORT(SessionProtocol, MessageCreateSession); 00055 WISP_IMPORT(SessionProtocol, MessageGetSession); 00056 WISP_IMPORT(SessionProtocol, MessageExpireSession); 00057 WISP_IMPORT(SessionProtocol, MessageSetAttributes); 00058 WISP_IMPORT(SessionProtocol, MessageUpdateSession); 00059 WISP_IMPORT(SessionProtocol, MessageLoginSession); 00060 WISP_IMPORT(SessionProtocol, MessageLogoutSession); 00061 00062 WISP_IMPORT(SessionProtocol, CallExpireSession); 00063 00064 private: 00065 struct TouchSession { 00066 idle_count_type idle_count; 00067 00068 TouchSession(const idle_count_type idle_count) : idle_count(idle_count) { } 00069 00070 void operator()(SessionData & session) { 00071 session.idle_count = idle_count; 00072 } 00073 }; 00074 00075 friend class NS_SSRC_WISP_SERVICE::ServiceProtocolProcessor<packing_traits>; 00076 typedef DictionaryService<SessionProtocol> super; 00077 00078 00079 const RandomId<std::int32_t> _random_id; 00080 const unsigned int _expirations_per_message; 00081 const sec_type _poll_interval; 00082 const sec_type _max_idle_time; 00083 idle_count_type _low_count; 00084 TouchSession _touch_session; 00085 timeout_ptr _poll_timeout; 00086 const std::string _checkpoint_path; 00087 00088 void load_checkpoint(const std::string & filename) 00089 SSRC_DECL_THROW(std::runtime_error, boost::archive::archive_exception); 00090 00091 void touch_session(const session_map::iterator & it) { 00092 if(it->idle_count != _touch_session.idle_count) { 00093 get_index<BySID>().modify(it, _touch_session); 00094 } 00095 } 00096 00097 virtual void process_request(const MessageInsert & msg, const MessageInfo &); 00098 00099 void process_request(const MessageCreateSession & msg, 00100 const MessageInfo & msginfo); 00101 00102 void process_request(const MessageGetSession & msg, 00103 const MessageInfo & msginfo); 00104 00105 void process_request(MessageSetAttributes & msg, const MessageInfo &); 00106 00107 void update_session(const SessionData & update); 00108 00109 void process_request(const MessageUpdateSession & msg, const MessageInfo &) { 00110 update_session(msg.session); 00111 } 00112 00113 void process_request(const MessageLoginSession & msg, const MessageInfo &) { 00114 update_session(msg.session); 00115 } 00116 00117 void process_request(const MessageLogoutSession & msg, const MessageInfo &); 00118 00122 void check_for_expirations() { 00123 // We don't worry about wraparound effects because the process will never 00124 // run long enough for wraparound even at a poll interval of one second. 00125 // Still, it's easy enough to handle if we have to. 00126 expire_sessions(_low_count); 00127 ++_low_count; 00128 ++_touch_session.idle_count; 00129 } 00130 00131 virtual void transition(State state); 00132 00133 public: 00134 00135 Session(super::caller_type & caller, const SessionInitializer & initializer) 00136 SSRC_DECL_THROW(std::runtime_error, boost::archive::archive_exception); 00137 00138 virtual ~Session() { } 00139 00140 string create_sid(); 00141 00142 string create_xsrf_token() { 00143 return _random_id(SessionIdNumChars); 00144 } 00145 00149 std::pair<session_map::iterator, bool> create_session() { 00150 return 00151 insert<BySID>(SessionData(create_sid(), create_xsrf_token(), 00152 _touch_session.idle_count)); 00153 } 00154 00155 void expire_sessions(const idle_count_type low_count); 00156 00157 }; 00158 00159 __END_NS_SSRC_WSPR_SESSION 00160 00161 #endif
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.