[macruby-changes] [4885] ControlTower/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Fri Nov 5 03:10:08 PDT 2010
Revision: 4885
http://trac.macosforge.org/projects/ruby/changeset/4885
Author: joshua.ballanco at apple.com
Date: 2010-11-05 03:10:04 -0700 (Fri, 05 Nov 2010)
Log Message:
-----------
Added GCD timer source based session store.
Modified Paths:
--------------
ControlTower/trunk/Rakefile
Added Paths:
-----------
ControlTower/trunk/lib/rack/session/
ControlTower/trunk/lib/rack/session/gcd.rb
Modified: ControlTower/trunk/Rakefile
===================================================================
--- ControlTower/trunk/Rakefile 2010-11-05 04:09:54 UTC (rev 4884)
+++ ControlTower/trunk/Rakefile 2010-11-05 10:10:04 UTC (rev 4885)
@@ -20,6 +20,7 @@
lib/control_tower/rack_socket.rb
lib/control_tower/server.rb
lib/rack/handler/control_tower.rb
+ lib/rack/session/gcd.rb
bin/control_tower
ext/CTParser/http11_parser.h
ext/CTParser/http11_parser.c
Added: ControlTower/trunk/lib/rack/session/gcd.rb
===================================================================
--- ControlTower/trunk/lib/rack/session/gcd.rb (rev 0)
+++ ControlTower/trunk/lib/rack/session/gcd.rb 2010-11-05 10:10:04 UTC (rev 4885)
@@ -0,0 +1,110 @@
+#
+# Copyright © 2010 Apple Inc. All rights reserved.
+#
+# IMPORTANT NOTE: This file is licensed only for use on Apple-branded computers
+# and is subject to the terms and conditions of the Apple Software License Agreement
+# accompanying the package this file is a part of. You may not port this file to
+# another platform without Apple's written consent.
+#
+
+require 'rack/session/abstract/id'
+
+module Rack
+ module Session
+ class GCDSession
+ attr_reader :session_id
+
+ def initialize(sid, store)
+ @session_id = sid
+ @session_store = store
+ @session_values = {}
+ @session_timer = nil
+ @session_expires_at = nil
+ @session_access_queue = Dispatch::Queue.new("session-#{sid}-access")
+
+ # Sessions are self expiring. This is the block that handles expiry. The first task is to cancel the timer so that it only
+ # fires once
+ @timer_block = lambda do |src|
+ @session_timer.cancel! unless @session_timer.nil?
+ time_remaining = @session_expires_at - Time.now
+ if time_remaining < 0
+ @session_store.delete(@session_id)
+ else
+ @session_timer = Dispatch::Source.timer(time_remaining, 500, 0.5, @session_access_queue, &@timer_block)
+ end
+ end
+ end
+
+ def set_timer(seconds)
+ # If this is the first time we're setting the timer, then we need to create the timer source as well
+ @session_timer ||= Dispatch::Source.timer(seconds, 500, 0.5, @session_access_queue, &@timer_block)
+ @session_access_queue.sync { @session_expires_at = Time.now + seconds }
+ end
+
+ def [](key)
+ @session_values[key]
+ end
+ alias :fetch :[]
+
+ def []=(key, value)
+ @session_access_queue.sync do
+ @session_values[key] = value
+ end
+ value
+ end
+ alias :store :[]=
+
+ def delete(key)
+ @session_access_queue.sync do
+ @session_values.delete(key)
+ end
+ end
+
+ def clear
+ @session_access_queue.sync do
+ @session_values.clear
+ end
+ end
+ end
+
+ class GCD < Abstract::ID
+ def initialize(app, options={})
+ super
+ @sessions = {}
+ end
+
+ # Use UUIDs for session keys and save time on uniqueness checks
+ def generate_sid
+ uuid = CFUUIDCreate(nil)
+ CFMakeCollectable(uuid)
+ uuid_string = CFUUIDCreateString(nil, uuid)
+ CFMakeCollectable(uuid_string)
+ uuid_string
+ end
+
+ def get_session(env, sid)
+ session = @sessions[sid] if sid
+ unless sid and session
+ env['rack.errors'].puts("Session '#{sid.inspect}' not found, initializing...") if $VERBOSE and not sid.nil?
+ sid = generate_sid
+ session = GCDSession.new(sid, @sessions)
+ @sessions[sid] = session
+ end
+ return sid, session
+ end
+
+ def set_session(env, sid, session, options)
+ session = @sessions[sid]
+ if options[:renew] or options[:drop]
+ @sessions.delete(sid)
+ return false if options[:drop]
+ session_id = generate_sid
+ @sessions[session_id] = 0
+ end
+ session ||= GCDSession.new(generate_sid, @sessions)
+ session.set_timer(options[:expire_after]) unless options[:expire_after].nil?
+ session.session_id
+ end
+ end
+ end
+end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20101105/b176b3f3/attachment-0001.html>
More information about the macruby-changes
mailing list