From: erickson Date: Thu, 11 Jun 2009 03:21:39 +0000 (+0000) Subject: added session callback support with example method. added method-not-found handling... X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=ce48750f6ab01d2d365b1f95a8188fda96308803;p=opensrf%2Fbjwebb.git added session callback support with example method. added method-not-found handling. added network socket flush for clearing stale inbound data. git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1718 9efc2488-bf62-4759-914b-345cdb29e865 --- diff --git a/src/python/osrf/app.py b/src/python/osrf/app.py index 45ef2b1..32eae70 100644 --- a/src/python/osrf/app.py +++ b/src/python/osrf/app.py @@ -103,7 +103,13 @@ class Application(object): req_method = osrf_msg.payload() params = req_method.params() or [] - method = Application.methods[req_method.method()] + method_name = req_method.method() + method = Application.methods.get(method_name) + + if method is None: + session.send_method_not_found(osrf_msg.threadTrace(), method_name) + return + handler = method.get_func() param_json = osrf.json.to_json(params) diff --git a/src/python/osrf/apps/example.py b/src/python/osrf/apps/example.py index 3c219d7..ede22f7 100644 --- a/src/python/osrf/apps/example.py +++ b/src/python/osrf/apps/example.py @@ -47,6 +47,8 @@ class Example(Application): idx -= 1 # --------------------------------------------------------- + # Session data test + # --------------------------------------------------------- Application.register_method( api_name = 'opensrf.stateful_session_test', @@ -60,6 +62,41 @@ class Example(Application): return c # --------------------------------------------------------- + # Session callbacks test + # --------------------------------------------------------- + Application.register_method( + api_name = 'opensrf.session_callback_test', + method = 'callback_test', + argc = 0 + ) + + def callback_test(self, request): + + def pre_req_cb(ses): + osrf.log.log_info("running pre_request callback") + + def post_req_cb(ses): + osrf.log.log_info("running post_request callback") + + def disconnect_cb(ses): + osrf.log.log_info("running disconnect callback") + + def death_cb(ses): + osrf.log.log_info("running death callback") + + ses = request.session + + ses.register_callback('pre_request', pre_req_cb) + ses.register_callback('post_request', post_req_cb) + ses.register_callback('disconnect', disconnect_cb) + ses.register_callback('death', death_cb) + + c = ses.session_data.get('counter', 0) + 1 + ses.session_data['counter'] = c + return c + + + # --------------------------------------------------------- # These example methods override methods from # osrf.app.Application. They are not required. # --------------------------------------------------------- diff --git a/src/python/osrf/net.py b/src/python/osrf/net.py index cad2e67..81b1da9 100644 --- a/src/python/osrf/net.py +++ b/src/python/osrf/net.py @@ -58,7 +58,6 @@ def clear_network_handle(): handle = THREAD_SESSIONS.get(threading.currentThread().getName()) if handle: osrf.log.log_internal("clearing network handle %s" % handle.jid.as_utf8()) - #handle.disconnect() del THREAD_SESSIONS[threading.currentThread().getName()] return handle @@ -247,4 +246,13 @@ class Network(JabberClient): return msg + def flush_inbound_data(self): + ''' Read all pending inbound messages from the socket and discard them ''' + cb = self.receive_callback + self.receive_callback = None + while self.recv(0): pass + self.receive_callback = cb + + + diff --git a/src/python/osrf/server.py b/src/python/osrf/server.py index 4b5d014..97a743a 100644 --- a/src/python/osrf/server.py +++ b/src/python/osrf/server.py @@ -300,6 +300,7 @@ class Child(object): size = int(self.read_data.recv(SIZE_PAD) or 0) data = self.read_data.recv(size) osrf.log.log_internal("recv'd data " + data) + osrf.net.get_network_handle().flush_inbound_data() session = osrf.stack.push(osrf.net.NetworkMessage.from_xml(data)) self.keepalive_loop(session) self.num_requests += 1 @@ -316,15 +317,13 @@ class Child(object): while session.state == osrf.const.OSRF_APP_SESSION_CONNECTED: - start = time.time() - session.wait(keepalive) - end = time.time() + status = session.wait(keepalive) if session.state == osrf.const.OSRF_APP_SESSION_DISCONNECTED: osrf.log.log_internal("client sent disconnect, exiting keepalive") break - if (end - start) >= keepalive: # exceeded keepalive timeout + if status is None: # no msg received before keepalive timeout expired osrf.log.log_info("No request was received in %d seconds, exiting stateful session" % int(keepalive)); @@ -338,6 +337,7 @@ class Child(object): break + session.run_callback('death') return def send_status(self): diff --git a/src/python/osrf/ses.py b/src/python/osrf/ses.py index 1628f9a..4d06d45 100644 --- a/src/python/osrf/ses.py +++ b/src/python/osrf/ses.py @@ -60,7 +60,7 @@ class Session(object): """Wait up to seconds for data to arrive on the network""" osrf.log.log_internal("Session.wait(%d)" % timeout) handle = osrf.net.get_network_handle() - handle.recv(timeout) + return handle.recv(timeout) def send(self, omessages): """Sends an OpenSRF message""" @@ -356,10 +356,24 @@ class ServerSession(Session): }) self.send_status(thread_trace, status_msg) + def send_method_not_found(self, thread_trace, method_name): + status_msg = osrf.net_obj.NetworkObject.osrfConnectStatus({ + 'status' : 'Method [%s] not found for %s' % (method_name, self.service), + 'statusCode': osrf.const.OSRF_STATUS_NOTFOUND + }) + self.send_status(thread_trace, status_msg) + + + def run_callback(self, type): + if type in self.callbacks: + self.callbacks[type](self) + + def register_callback(self, type, func): + self.callbacks[type] = func + def cleanup(self): Session.cleanup(self) - if 'death' in self.callbacks: - self.callbacks['death'](self) + self.run_callbacks('death') class ServerRequest(Request): diff --git a/src/python/osrf/stack.py b/src/python/osrf/stack.py index 417b431..f0240f8 100644 --- a/src/python/osrf/stack.py +++ b/src/python/osrf/stack.py @@ -101,7 +101,9 @@ def handle_server(session, message): if message.type() == osrf.const.OSRF_MESSAGE_TYPE_REQUEST: osrf.log.log_debug("server received REQUEST from %s" % session.remote_id) + session.run_callback('pre_request') osrf.app.Application.handle_request(session, message) + session.run_callback('post_request') return if message.type() == osrf.const.OSRF_MESSAGE_TYPE_CONNECT: @@ -113,11 +115,15 @@ def handle_server(session, message): if message.type() == osrf.const.OSRF_MESSAGE_TYPE_DISCONNECT: osrf.log.log_debug("server received DISCONNECT from %s" % session.remote_id) session.state = osrf.const.OSRF_APP_SESSION_DISCONNECTED + session.run_callback('disconnect') return if message.type() == osrf.const.OSRF_MESSAGE_TYPE_STATUS: - # Should never get here - osrf.log.log_warn("server received STATUS from %s" % session.remote_id) + osrf.log.log_debug("server ignoring STATUS from %s" % session.remote_id) + return + + if message.type() == osrf.const.OSRF_MESSAGE_TYPE_RESULT: + osrf.log.log_debug("server ignoring RESULT from %s" % session.remote_id) return