Class: Wee::Session
- Inherits:
-
RequestHandler
- Object
- RequestHandler
- Wee::Session
- Defined in:
- lib/wee/session.rb,
lib/wee/continuation/session.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#page_store ⇒ Object
Returns the value of attribute page_store.
-
#properties ⇒ Object
-
:section: Properties - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -.
-
-
#root_component ⇒ Object
Returns the value of attribute root_component.
Attributes inherited from RequestHandler
#application, #expire_after, #id, #max_lifetime, #max_requests
Class Method Summary collapse
Instance Method Summary collapse
-
#awake ⇒ Object
Is called before process_request is invoked Can be used to setup e.g.
- #create_page(snapshot) ⇒ Object
- #current_callbacks ⇒ Object
- #current_context ⇒ Object
-
#get_property(prop, klass) ⇒ Object
Returns an “owned” property for the given
klass. -
#handle_request(context) ⇒ Object
called by application to send the session a request.
-
#initialize(&block) ⇒ Session
constructor
A new instance of Session.
- #process_request ⇒ Object
-
#sleep ⇒ Object
Is called after process_request is run Can be used to release e.g.
- #snapshot ⇒ Object
- #start_request_response_loop ⇒ Object
Methods inherited from RequestHandler
#alive?, #statistics, #teminate
Constructor Details
#initialize(&block) ⇒ Session
Returns a new instance of Session.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/wee/session.rb', line 13 def initialize(&block) Thread.current[:wee_session] = self @idgen = Wee::SimpleIdGenerator.new # to serialize the requests we need a mutex @mutex = Mutex.new block.call(self) raise ArgumentError, "No root component specified" if @root_component.nil? raise ArgumentError, "No page_store specified" if @page_store.nil? @initial_snapshot = snapshot() super() ensure Thread.current[:wee_session] = nil end |
Instance Attribute Details
#page_store ⇒ Object
Returns the value of attribute page_store.
5 6 7 |
# File 'lib/wee/session.rb', line 5 def page_store @page_store end |
#properties ⇒ Object
-
-
-
:section: Properties
-
-
-
161 162 163 |
# File 'lib/wee/session.rb', line 161 def properties @properties end |
#root_component ⇒ Object
Returns the value of attribute root_component.
5 6 7 |
# File 'lib/wee/session.rb', line 5 def root_component @root_component end |
Class Method Details
.current ⇒ Object
7 8 9 10 11 |
# File 'lib/wee/session.rb', line 7 def self.current sess = Thread.current[:wee_session] raise "not in session" if sess.nil? return sess end |
Instance Method Details
#awake ⇒ Object
Is called before process_request is invoked Can be used to setup e.g. a database connection.
66 67 |
# File 'lib/wee/session.rb', line 66 def awake end |
#create_page(snapshot) ⇒ Object
59 60 61 62 |
# File 'lib/wee/session.rb', line 59 def create_page(snapshot) idgen = Wee::SimpleIdGenerator.new page = Wee::Page.new(snapshot, Wee::CallbackRegistry.new(idgen)) end |
#current_callbacks ⇒ Object
153 154 155 |
# File 'lib/wee/session.rb', line 153 def current_callbacks @page.callbacks end |
#current_context ⇒ Object
149 150 151 |
# File 'lib/wee/session.rb', line 149 def current_context @context end |
#get_property(prop, klass) ⇒ Object
Returns an “owned” property for the given klass.
165 166 167 168 169 170 171 |
# File 'lib/wee/session.rb', line 165 def get_property(prop, klass) if @properties @properties.fetch(klass, {})[prop] else nil end end |
#handle_request(context) ⇒ Object
called by application to send the session a request
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/wee/session.rb', line 40 def handle_request(context) @mutex.synchronize do begin Thread.current[:wee_session] = self @context = context super awake process_request sleep rescue Exception => exn set_response(context, Wee::ErrorResponse.new(exn)) ensure Thread.current[:wee_session] = nil @context = nil @page = nil end end end |
#process_request ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/wee/session.rb', line 74 def process_request if @context.request.page_id.nil? # No page_id was specified in the URL. This means that we start with a # fresh component and a fresh page_id, then redirect to render itself. handle_new_page_view(@context, @initial_snapshot) elsif @page = @page_store.fetch(@context.request.page_id, false) # A valid page_id was specified and the corresponding page exists. @page.snapshot.restore if @context.request.page_id != @snapshot_page_id p @context.request.fields if $DEBUG if @context.request.fields.empty? # No action/inputs were specified -> render page # # 1. Reset the action/input fields (as they are regenerated in the # rendering process). # 2. Render the page (respond). # 3. Store the page back into the store @page = create_page(@page.snapshot) # remove all action/input handlers respond(@context, @page.callbacks) # render @page_store[@context.request.page_id] = @page # store else # Actions/inputs were specified. # # We process the request and invoke actions/inputs. Then we generate a # new page view. callback_stream = Wee::CallbackStream.new(@page.callbacks, @context.request.fields) if callback_stream.all_of_type(:action).size > 1 raise "Not allowed to specify more than one action callback" end live_update_response = catch(:wee_live_update) { catch(:wee_back_to_session) { @root_component.process_callbacks_chain(callback_stream) } nil } if live_update_response # replace existing page with new snapshot @page.snapshot = self.snapshot @page_store[@context.request.page_id] = @page @snapshot_page_id = @context.request.page_id set_response(@context, live_update_response) else handle_new_page_view(@context) end end else # A page_id was specified in the URL, but there's no page for it in the # page store. Either the page has timed out, or an invalid page_id was # specified. # # TODO:: Display an "invalid page or page timed out" message, which # forwards to /app/session-id raise "Not yet implemented" end end |
#sleep ⇒ Object
Is called after process_request is run Can be used to release e.g. a database connection.
71 72 |
# File 'lib/wee/session.rb', line 71 def sleep end |
#snapshot ⇒ Object
33 34 35 36 |
# File 'lib/wee/session.rb', line 33 def snapshot @root_component.backtrack_state_chain(snap = Wee::Snapshot.new) return snap.freeze end |
#start_request_response_loop ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/wee/continuation/session.rb', line 35 def start_request_response_loop Thread.abort_on_exception = true Thread.new { Thread.current[:wee_session] = self loop { @context = nil # get a request, check whether this session is alive after every 5 # seconds. while @context.nil? begin Timeout.timeout(5) { @context = @in_queue.pop } rescue Timeout::Error break unless alive? end end # abort thread if no longer alive break if not alive? raise "invalid request" if @context.nil? begin awake process_request sleep rescue Exception => exn @context.response = Wee::ErrorResponse.new(exn) end @out_queue.push(@context) } p "session loop terminated" if $DEBUG } end |