Continue the march towards a pedantic 1.0 python API.
[OpenSRF.git] / src / python / osrf / stack.py
1 # -----------------------------------------------------------------------
2 # Copyright (C) 2007  Georgia Public Library Service
3 # Bill Erickson <billserickson@gmail.com>
4
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 # -----------------------------------------------------------------------
15
16 import osrf.json
17 import osrf.log
18 import osrf.ex
19 import osrf.ses
20 from osrf.const import OSRF_APP_SESSION_CONNECTED, \
21     OSRF_APP_SESSION_DISCONNECTED, OSRF_MESSAGE_TYPE_RESULT, \
22     OSRF_MESSAGE_TYPE_STATUS, OSRF_STATUS_COMPLETE, OSRF_STATUS_CONTINUE, \
23     OSRF_STATUS_NOTFOUND, OSRF_STATUS_OK, OSRF_STATUS_TIMEOUT
24 import time
25
26
27 def push(net_msg):
28     ses = osrf.ses.Session.find_session(net_msg.thread)
29
30     if not ses:
31         # This is an incoming request from a client, create a new server session
32         osrf.log.log_error("server-side sessions don't exist yet")
33
34     ses.set_remote_id(net_msg.sender)
35
36     omessages = osrf.json.to_object(net_msg.body)
37
38     osrf.log.log_internal("push(): received %d messages" \
39         % len(omessages))
40
41     # Pass each bundled opensrf message to the message handler
42     start = time.time()
43     for msg in omessages:
44         handle_message(ses, msg)
45     duration = time.time() - start
46
47     if isinstance(ses, osrf.ses.ServerSession):
48         osrf.log.log_info("Message processing duration %f" % duration)
49
50 def handle_message(session, message):
51
52     osrf.log.log_internal("handle_message(): processing message of "
53         "type %s" % message.type())
54
55     if isinstance(session, osrf.ses.ClientSession):
56
57         if message.type() == OSRF_MESSAGE_TYPE_RESULT:
58             session.push_response_queue(message)
59             return
60
61         if message.type() == OSRF_MESSAGE_TYPE_STATUS:
62
63             status_code = int(message.payload().statusCode())
64             status_text = message.payload().status()
65             osrf.log.log_internal("handle_message(): processing STATUS, "
66                 "status_code =  %d" % status_code)
67
68         if status_code == OSRF_STATUS_COMPLETE:
69             # The server has informed us that this request is complete
70             req = session.find_request(message.threadTrace())
71             if req: 
72                 osrf.log.log_internal("marking request as complete: %d" % req.rid)
73                 req.set_complete()
74             return
75
76         if status_code == OSRF_STATUS_OK:
77             # We have connected successfully
78             osrf.log.log_debug("Successfully connected to " + session.service)
79             session.state = OSRF_APP_SESSION_CONNECTED
80             return
81
82         if status_code == OSRF_STATUS_CONTINUE:
83             # server is telling us to reset our wait timeout and keep waiting for a response
84             session.reset_request_timeout(message.threadTrace())
85             return
86
87         if status_code == OSRF_STATUS_TIMEOUT:
88             osrf.log.log_debug("The server did not receive a request from us in time...")
89             session.state = OSRF_APP_SESSION_DISCONNECTED
90             return
91
92         if status_code == OSRF_STATUS_NOTFOUND:
93             osrf.log.log_error("Requested method was not found on the server: %s" % status_text)
94             session.state = OSRF_APP_SESSION_DISCONNECTED
95             raise osrf.ex.OSRFServiceException(status_text)
96
97         raise osrf.ex.OSRFProtocolException("Unknown message status: %d" % status_code)
98
99
100
101