基于HTTP的后端Handler实现 .. note:: Don't need a lock when access HttpHandler._webio_sessions, See: https://stackoverflow.com/questions/1312331/using-a-global-dictionary-with-threads-in-python
| 145 | |
| 146 | # todo: use lock to avoid thread race condition |
| 147 | class HttpHandler: |
| 148 | """基于HTTP的后端Handler实现 |
| 149 | |
| 150 | .. note:: |
| 151 | Don't need a lock when access HttpHandler._webio_sessions, See: |
| 152 | https://stackoverflow.com/questions/1312331/using-a-global-dictionary-with-threads-in-python |
| 153 | |
| 154 | """ |
| 155 | _webio_sessions = {} # WebIOSessionID -> WebIOSession() |
| 156 | _webio_transports = {} # WebIOSessionID -> ReliableTransport(), type: Dict[str, ReliableTransport] |
| 157 | _webio_expire = LRUDict() # WebIOSessionID -> last active timestamp. In increasing order of last active time |
| 158 | _webio_expire_lock = threading.Lock() |
| 159 | |
| 160 | _last_check_session_expire_ts = 0 # Timestamp of the last check session validation |
| 161 | |
| 162 | # After processing the POST request, wait for WAIT_MS_ON_POST milliseconds before generate response |
| 163 | WAIT_MS_ON_POST = 100 |
| 164 | |
| 165 | DEFAULT_SESSION_EXPIRE_SECONDS = 600 # Default session expiration time |
| 166 | DEFAULT_SESSIONS_CLEANUP_INTERVAL = 300 # Default interval for clearing expired sessions (in seconds) |
| 167 | |
| 168 | @classmethod |
| 169 | def _remove_expired_sessions(cls, session_expire_seconds): |
| 170 | """清除当前会话列表中的过期会话""" |
| 171 | logger.debug("removing expired sessions") |
| 172 | while cls._webio_expire: |
| 173 | sid, active_ts = cls._webio_expire.popitem(last=False) # 弹出最不活跃的session info |
| 174 | |
| 175 | if time.time() - active_ts < session_expire_seconds: |
| 176 | # this session is not expired |
| 177 | cls._webio_expire[sid] = active_ts |
| 178 | cls._webio_expire.move_to_end(sid, last=False) |
| 179 | break |
| 180 | |
| 181 | # clean this session |
| 182 | logger.debug("session %s expired" % sid) |
| 183 | session = cls._webio_sessions.get(sid) |
| 184 | if session: |
| 185 | session.close(nonblock=True) |
| 186 | del cls._webio_sessions[sid] |
| 187 | del cls._webio_transports[sid] |
| 188 | |
| 189 | @classmethod |
| 190 | def _remove_webio_session(cls, sid): |
| 191 | cls._webio_sessions.pop(sid, None) |
| 192 | cls._webio_expire.pop(sid, None) |
| 193 | |
| 194 | def _process_cors(self, context: HttpContext): |
| 195 | """Handling cross-domain requests: check the source of the request and set headers""" |
| 196 | origin = context.request_headers().get('Origin', '') |
| 197 | if self.check_origin(origin): |
| 198 | context.set_header('Access-Control-Allow-Origin', origin) |
| 199 | context.set_header('Access-Control-Allow-Methods', 'GET, POST') |
| 200 | context.set_header('Access-Control-Allow-Headers', 'content-type, webio-session-id') |
| 201 | context.set_header('Access-Control-Expose-Headers', 'webio-session-id') |
| 202 | context.set_header('Access-Control-Max-Age', str(1440 * 60)) |
| 203 | |
| 204 | def interval_cleaning(self): |
no test coverage detected
searching dependent graphs…