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 Session class.
20 : : */
21 : :
22 : : #ifndef __SSRC_WSPR_SESSION_SERVICE_H
23 : : #define __SSRC_WSPR_SESSION_SERVICE_H
24 : :
25 : : #include <ssrc/wispers/index/DictionaryService.h>
26 : : #include <ssrc/wispers/session/protocol.h>
27 : : #include <ssrc/wispers/utility/RandomId.h>
28 : :
29 : : __BEGIN_NS_SSRC_WSPR_SESSION
30 : :
31 : : using NS_SSRC_WSPR_SERVICE::timeout_ptr;
32 : : using NS_SSRC_WSPR_UTILITY::RandomId;
33 : :
34 : 5 : struct SessionInitializer {
35 : : unsigned int expirations_per_message;
36 : : // These are in seconds. For best results, max_idle_time should be
37 : : // an integer multiple of poll_interval.
38 : : unsigned int poll_interval;
39 : : unsigned int max_idle_time;
40 : : std::string checkpoint_path;
41 : :
42 : 5 : SessionInitializer() :
43 : 5 : expirations_per_message(1024), poll_interval(300), max_idle_time(1800)
44 : 5 : { }
45 : : };
46 : :
47 : : /**
48 : : *
49 : : */
50 : : class Session : public DictionaryService<SessionProtocol> {
51 : : public:
52 : : WISP_IMPORT(SessionProtocol, MessageSingleQueryResult);
53 : : WISP_IMPORT(SessionProtocol, MessageInsert);
54 : : WISP_IMPORT(SessionProtocol, MessageCreateSession);
55 : : WISP_IMPORT(SessionProtocol, MessageGetSession);
56 : : WISP_IMPORT(SessionProtocol, MessageExpireSession);
57 : : WISP_IMPORT(SessionProtocol, MessageSetAttributes);
58 : : WISP_IMPORT(SessionProtocol, MessageUpdateSession);
59 : : WISP_IMPORT(SessionProtocol, MessageLoginSession);
60 : : WISP_IMPORT(SessionProtocol, MessageLogoutSession);
61 : :
62 : : WISP_IMPORT(SessionProtocol, CallExpireSession);
63 : :
64 : : private:
65 : : struct TouchSession {
66 : : idle_count_type idle_count;
67 : :
68 : 5 : TouchSession(const idle_count_type idle_count) : idle_count(idle_count) { }
69 : :
70 : 0 : void operator()(SessionData & session) {
71 : 0 : session.idle_count = idle_count;
72 : 0 : }
73 : : };
74 : :
75 : : friend class NS_SSRC_WISP_SERVICE::ServiceProtocolProcessor<packing_traits>;
76 : : typedef DictionaryService<SessionProtocol> super;
77 : :
78 : :
79 : : const RandomId<std::int32_t> _random_id;
80 : : const unsigned int _expirations_per_message;
81 : : const sec_type _poll_interval;
82 : : const sec_type _max_idle_time;
83 : : idle_count_type _low_count;
84 : : TouchSession _touch_session;
85 : : timeout_ptr _poll_timeout;
86 : : const std::string _checkpoint_path;
87 : :
88 : : void load_checkpoint(const std::string & filename)
89 : : SSRC_DECL_THROW(std::runtime_error, boost::archive::archive_exception);
90 : :
91 : 6 : void touch_session(const session_map::iterator & it) {
92 [ - + ]: 6 : if(it->idle_count != _touch_session.idle_count) {
93 : 0 : get_index<BySID>().modify(it, _touch_session);
94 : : }
95 : 6 : }
96 : :
97 : : virtual void process_request(const MessageInsert & msg, const MessageInfo &);
98 : :
99 : : void process_request(const MessageCreateSession & msg,
100 : : const MessageInfo & msginfo);
101 : :
102 : : void process_request(const MessageGetSession & msg,
103 : : const MessageInfo & msginfo);
104 : :
105 : : void process_request(MessageSetAttributes & msg, const MessageInfo &);
106 : :
107 : : void update_session(const SessionData & update);
108 : :
109 : 0 : void process_request(const MessageUpdateSession & msg, const MessageInfo &) {
110 : 0 : update_session(msg.session);
111 : 0 : }
112 : :
113 : 0 : void process_request(const MessageLoginSession & msg, const MessageInfo &) {
114 : 0 : update_session(msg.session);
115 : 0 : }
116 : :
117 : : void process_request(const MessageLogoutSession & msg, const MessageInfo &);
118 : :
119 : : /**
120 : : *
121 : : */
122 : 0 : void check_for_expirations() {
123 : : // We don't worry about wraparound effects because the process will never
124 : : // run long enough for wraparound even at a poll interval of one second.
125 : : // Still, it's easy enough to handle if we have to.
126 : 0 : expire_sessions(_low_count);
127 : 0 : ++_low_count;
128 : 0 : ++_touch_session.idle_count;
129 : 0 : }
130 : :
131 : : virtual void transition(State state);
132 : :
133 : : public:
134 : :
135 : : Session(super::caller_type & caller, const SessionInitializer & initializer)
136 : : SSRC_DECL_THROW(std::runtime_error, boost::archive::archive_exception);
137 : :
138 [ + - + - : 5 : virtual ~Session() { }
+ - - + ]
139 : :
140 : : string create_sid();
141 : :
142 : 6 : string create_xsrf_token() {
143 : 6 : return _random_id(SessionIdNumChars);
144 : : }
145 : :
146 : : /**
147 : : *
148 : : */
149 : 6 : std::pair<session_map::iterator, bool> create_session() {
150 : : return
151 [ + - + - ]: 6 : insert<BySID>(SessionData(create_sid(), create_xsrf_token(),
152 [ + - + - : 12 : _touch_session.idle_count));
+ - + - +
- + - ]
153 : : }
154 : :
155 : : void expire_sessions(const idle_count_type low_count);
156 : :
157 : : };
158 : :
159 : : __END_NS_SSRC_WSPR_SESSION
160 : :
161 : : #endif
|