cramp 0.5 → 0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/cramp/controller/abstract.rb +59 -0
- data/lib/cramp/controller/action.rb +22 -0
- data/lib/cramp/controller/body.rb +13 -4
- data/lib/cramp/controller/callbacks.rb +58 -0
- data/lib/cramp/controller/keep_connection_alive.rb +21 -0
- data/lib/cramp/controller/periodic_timer.rb +51 -0
- data/lib/cramp/controller/rendering.rb +13 -0
- data/lib/cramp/controller/test_case.rb +57 -0
- data/lib/cramp/controller.rb +7 -6
- data/lib/cramp/core_ext.rb +4 -0
- data/lib/cramp/model/base.rb +13 -7
- data/lib/cramp/model/finders.rb +5 -11
- data/lib/cramp/model/relation.rb +16 -14
- data/lib/cramp/model/status.rb +2 -0
- data/lib/cramp/model.rb +9 -0
- data/lib/cramp.rb +5 -2
- metadata +10 -3
- data/lib/cramp/controller/base.rb +0 -114
@@ -0,0 +1,59 @@
|
|
1
|
+
module Cramp
|
2
|
+
module Controller
|
3
|
+
class Abstract
|
4
|
+
|
5
|
+
include Callbacks
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def call(env)
|
9
|
+
controller = new(env).process
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(env)
|
14
|
+
@env = env
|
15
|
+
end
|
16
|
+
|
17
|
+
def process
|
18
|
+
EM.next_tick { before_start }
|
19
|
+
ASYNC_RESPONSE
|
20
|
+
end
|
21
|
+
|
22
|
+
def continue
|
23
|
+
init_async_body
|
24
|
+
|
25
|
+
status, headers = respond_with
|
26
|
+
send_initial_response(status, headers, @body)
|
27
|
+
|
28
|
+
EM.next_tick { start } if respond_to?(:start)
|
29
|
+
EM.next_tick { on_start }
|
30
|
+
end
|
31
|
+
|
32
|
+
def respond_with
|
33
|
+
[200, {'Content-Type' => 'text/html'}]
|
34
|
+
end
|
35
|
+
|
36
|
+
def init_async_body
|
37
|
+
@body = Body.new
|
38
|
+
|
39
|
+
if self.class.on_finish_callbacks.any?
|
40
|
+
@body.callback { on_finish }
|
41
|
+
@body.errback { on_finish }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def finish
|
46
|
+
@body.succeed
|
47
|
+
end
|
48
|
+
|
49
|
+
def send_initial_response(response_status, response_headers, response_body)
|
50
|
+
EM.next_tick { @env['async.callback'].call [response_status, response_headers, response_body] }
|
51
|
+
end
|
52
|
+
|
53
|
+
def halt(status, headers = {}, halt_body = '')
|
54
|
+
send_initial_response(status, headers, halt_body)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Cramp
|
2
|
+
module Controller
|
3
|
+
class Action < Abstract
|
4
|
+
|
5
|
+
include PeriodicTimer
|
6
|
+
include KeepConnectionAlive
|
7
|
+
|
8
|
+
def request
|
9
|
+
@request ||= Rack::Request.new(@env)
|
10
|
+
end
|
11
|
+
|
12
|
+
def params
|
13
|
+
@params ||= @env['usher.params']
|
14
|
+
end
|
15
|
+
|
16
|
+
def render(body)
|
17
|
+
@body.call(body)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
#
|
1
|
+
# Copyright 2008 James Tucker <raggi@rubyforge.org>.
|
2
2
|
|
3
3
|
module Cramp
|
4
4
|
module Controller
|
5
5
|
class Body
|
6
|
-
|
7
6
|
include EventMachine::Deferrable
|
8
7
|
|
9
8
|
def initialize
|
10
9
|
@queue = []
|
10
|
+
|
11
|
+
# Make sure to flush out the queue before closing the connection
|
12
|
+
callback { flush }
|
11
13
|
end
|
12
14
|
|
13
15
|
def call(body)
|
@@ -24,14 +26,21 @@ module Cramp
|
|
24
26
|
@deferred_status != :unknown
|
25
27
|
end
|
26
28
|
|
27
|
-
|
29
|
+
def flush
|
30
|
+
return unless @body_callback
|
31
|
+
|
32
|
+
until @queue.empty?
|
33
|
+
@queue.shift.each {|chunk| @body_callback.call(chunk) }
|
34
|
+
end
|
35
|
+
end
|
28
36
|
|
29
37
|
def schedule_dequeue
|
30
38
|
return unless @body_callback
|
39
|
+
|
31
40
|
EventMachine.next_tick do
|
32
41
|
next unless body = @queue.shift
|
33
42
|
|
34
|
-
body.each{|chunk| @body_callback.call(chunk) }
|
43
|
+
body.each {|chunk| @body_callback.call(chunk) }
|
35
44
|
schedule_dequeue unless @queue.empty?
|
36
45
|
end
|
37
46
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Cramp
|
2
|
+
module Controller
|
3
|
+
module Callbacks
|
4
|
+
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
ASYNC_RESPONSE = [-1, {}, []].freeze
|
8
|
+
DEFAULT_STATUS = 200
|
9
|
+
DEFAULT_HEADERS = { 'Content-Type' => 'text/html' }.freeze
|
10
|
+
|
11
|
+
included do
|
12
|
+
class_inheritable_accessor :default_status, :default_headers, :instance_reader => false
|
13
|
+
self.default_status = DEFAULT_STATUS
|
14
|
+
self.default_headers = DEFAULT_HEADERS
|
15
|
+
|
16
|
+
class_inheritable_accessor :before_start_callbacks, :on_finish_callbacks, :on_start_callback, :instance_reader => false
|
17
|
+
self.before_start_callbacks = []
|
18
|
+
self.on_finish_callbacks = []
|
19
|
+
self.on_start_callback = []
|
20
|
+
end
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
def before_start(*methods)
|
24
|
+
self.before_start_callbacks += methods
|
25
|
+
end
|
26
|
+
|
27
|
+
def on_finish(*methods)
|
28
|
+
self.on_finish_callbacks += methods
|
29
|
+
end
|
30
|
+
|
31
|
+
def on_start(*methods)
|
32
|
+
self.on_start_callback += methods
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def before_start(n = 0)
|
37
|
+
if callback = self.class.before_start_callbacks[n]
|
38
|
+
EM.next_tick { send(callback) { before_start(n+1) } }
|
39
|
+
else
|
40
|
+
continue
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def on_start
|
45
|
+
self.class.on_start_callback.each do |callback|
|
46
|
+
EM.next_tick { send(callback) }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def on_finish
|
51
|
+
self.class.on_finish_callbacks.each do |callback|
|
52
|
+
EM.next_tick { send(callback) }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Cramp
|
2
|
+
module Controller
|
3
|
+
module KeepConnectionAlive
|
4
|
+
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
include PeriodicTimer
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def keep_connection_alive(options = {})
|
10
|
+
options = { :every => 15 }.merge(options)
|
11
|
+
periodic_timer :keep_connection_alive, options
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def keep_connection_alive
|
16
|
+
render " "
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Cramp
|
2
|
+
module Controller
|
3
|
+
module PeriodicTimer
|
4
|
+
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
class_inheritable_accessor :periodic_timers, :instance_reader => false
|
9
|
+
self.periodic_timers ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def periodic_timer(method, options = {})
|
14
|
+
self.periodic_timers << [method, options]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(*)
|
19
|
+
super
|
20
|
+
@timers = []
|
21
|
+
end
|
22
|
+
|
23
|
+
def continue
|
24
|
+
super
|
25
|
+
EM.next_tick { start_periodic_timers }
|
26
|
+
end
|
27
|
+
|
28
|
+
def init_async_body
|
29
|
+
super
|
30
|
+
|
31
|
+
if self.class.periodic_timers.any?
|
32
|
+
@body.callback { stop_periodic_timers }
|
33
|
+
@body.errback { stop_periodic_timers }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def start_periodic_timers
|
40
|
+
self.class.periodic_timers.each do |method, options|
|
41
|
+
@timers << EventMachine::PeriodicTimer.new(options[:every] || 1) { send(method) }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def stop_periodic_timers
|
46
|
+
@timers.each {|t| t.cancel }
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/test_case'
|
3
|
+
|
4
|
+
module Cramp
|
5
|
+
module Controller
|
6
|
+
class TestCase < ::ActiveSupport::TestCase
|
7
|
+
|
8
|
+
setup :create_request
|
9
|
+
|
10
|
+
def create_request
|
11
|
+
@request = Rack::MockRequest.new(app)
|
12
|
+
end
|
13
|
+
|
14
|
+
def get(path, options = {}, headers = {}, &block)
|
15
|
+
callback = options.delete(:callback) || block
|
16
|
+
headers = headers.merge('async.callback' => callback)
|
17
|
+
|
18
|
+
EM.run { @request.get(path, headers) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_body(path, options = {}, headers = {}, &block)
|
22
|
+
callback = options.delete(:callback) || block
|
23
|
+
response_callback = proc {|response| response[-1].each {|chunk| callback.call(chunk) } }
|
24
|
+
headers = headers.merge('async.callback' => response_callback)
|
25
|
+
|
26
|
+
EM.run { @request.get(path, headers) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_body_chunks(path, options = {}, headers = {}, &block)
|
30
|
+
callback = options.delete(:callback) || block
|
31
|
+
count = options.delete(:count) || 1
|
32
|
+
|
33
|
+
stopping = false
|
34
|
+
chunks = []
|
35
|
+
|
36
|
+
get_body(path, options, headers) do |body_chunk|
|
37
|
+
chunks << body_chunk unless stopping
|
38
|
+
|
39
|
+
if chunks.count >= count
|
40
|
+
stopping = true
|
41
|
+
callback.call(chunks) if callback
|
42
|
+
EM.next_tick { EM.stop }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def app
|
48
|
+
raise "Please define a method called 'app' returning an async Rack Application"
|
49
|
+
end
|
50
|
+
|
51
|
+
def stop
|
52
|
+
EM.stop
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
data/lib/cramp/controller.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
|
-
|
2
|
-
require 'active_support'
|
3
|
-
require 'active_support/concern'
|
4
|
-
require 'active_support/core_ext/hash/indifferent_access'
|
5
|
-
|
1
|
+
require 'cramp'
|
6
2
|
require 'usher'
|
7
3
|
require 'rack'
|
8
4
|
|
9
5
|
module Cramp
|
10
6
|
module Controller
|
11
|
-
autoload :
|
7
|
+
autoload :Action, "cramp/controller/action"
|
12
8
|
autoload :Body, "cramp/controller/body"
|
9
|
+
autoload :PeriodicTimer, "cramp/controller/periodic_timer"
|
10
|
+
autoload :KeepConnectionAlive, "cramp/controller/keep_connection_alive"
|
11
|
+
autoload :Abstract, "cramp/controller/abstract"
|
12
|
+
autoload :Callbacks, "cramp/controller/callbacks"
|
13
|
+
autoload :TestCase, "cramp/controller/test_case"
|
13
14
|
end
|
14
15
|
end
|
data/lib/cramp/model/base.rb
CHANGED
@@ -38,17 +38,21 @@ module Cramp
|
|
38
38
|
@new_record
|
39
39
|
end
|
40
40
|
|
41
|
-
def save(&block)
|
41
|
+
def save(callback = nil, &block)
|
42
|
+
callback ||= block
|
43
|
+
|
42
44
|
if valid?
|
43
|
-
new_record? ? create_record(
|
45
|
+
new_record? ? create_record(callback) : update_record(callback)
|
44
46
|
else
|
45
|
-
|
47
|
+
callback.arity == 1 ? callback.call(Status.new(self, false)) : callback.call if callback
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
49
51
|
private
|
50
52
|
|
51
|
-
def create_record(&block)
|
53
|
+
def create_record(callback = nil, &block)
|
54
|
+
callback ||= block
|
55
|
+
|
52
56
|
self.class.arel_table.insert(arel_attributes(true)) do |new_id|
|
53
57
|
if new_id.present?
|
54
58
|
self.id = new_id
|
@@ -58,15 +62,17 @@ module Cramp
|
|
58
62
|
saved = false
|
59
63
|
end
|
60
64
|
|
61
|
-
|
65
|
+
callback.arity == 1 ? callback.call(Status.new(self, saved)) : callback.call if callback
|
62
66
|
end
|
63
67
|
end
|
64
68
|
|
65
|
-
def update_record(&block)
|
69
|
+
def update_record(callback = nil, &block)
|
70
|
+
callback ||= block
|
71
|
+
|
66
72
|
relation = self.class.arel_table.where(self.class[self.class.primary_key].eq(send(self.class.primary_key)))
|
67
73
|
|
68
74
|
relation.update(arel_attributes) do |updated_rows|
|
69
|
-
|
75
|
+
callback.arity == 1 ? callback.call(updated_rows) : callback.call if callback
|
70
76
|
end
|
71
77
|
end
|
72
78
|
|
data/lib/cramp/model/finders.rb
CHANGED
@@ -2,17 +2,7 @@ module Cramp
|
|
2
2
|
module Model
|
3
3
|
module Finders
|
4
4
|
|
5
|
-
|
6
|
-
Relation.new(self, arel_table)
|
7
|
-
end
|
8
|
-
|
9
|
-
def first(&block)
|
10
|
-
Relation.new(self, arel_table).limit(1).each(&block)
|
11
|
-
end
|
12
|
-
|
13
|
-
def where(relation)
|
14
|
-
Relation.new(self, arel_table.where(relation))
|
15
|
-
end
|
5
|
+
delegate :all, :first, :each, :where, :select, :group, :order, :limit, :offset, :to => :relation
|
16
6
|
|
17
7
|
def [](attribute)
|
18
8
|
arel_table[attribute]
|
@@ -22,6 +12,10 @@ module Cramp
|
|
22
12
|
@arel_table ||= Arel::Table.new(table_name)
|
23
13
|
end
|
24
14
|
|
15
|
+
def relation
|
16
|
+
Relation.new(self, arel_table)
|
17
|
+
end
|
18
|
+
|
25
19
|
private
|
26
20
|
|
27
21
|
def table_name
|
data/lib/cramp/model/relation.rb
CHANGED
@@ -6,37 +6,39 @@ module Cramp
|
|
6
6
|
@klass, @relation = klass, relation
|
7
7
|
end
|
8
8
|
|
9
|
-
def each(&block)
|
9
|
+
def each(callback = nil, &block)
|
10
|
+
callback ||= block
|
11
|
+
|
10
12
|
@relation.each do |row|
|
11
13
|
object = @klass.instantiate(row)
|
12
|
-
|
14
|
+
callback.call(object)
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
16
|
-
def all(&block)
|
18
|
+
def all(callback = nil, &block)
|
19
|
+
callback ||= block
|
20
|
+
|
17
21
|
@relation.all do |rows|
|
18
22
|
objects = rows.map {|r| @klass.instantiate(r) }
|
19
|
-
|
23
|
+
callback.call(objects)
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
23
|
-
def first(&block)
|
27
|
+
def first(callback = nil, &block)
|
28
|
+
callback ||= block
|
29
|
+
|
24
30
|
@relation.first do |row|
|
25
31
|
object = row ? @klass.instantiate(row) : nil
|
26
|
-
|
32
|
+
callback.call(object)
|
27
33
|
end
|
28
34
|
end
|
29
35
|
|
30
|
-
def
|
31
|
-
Relation.new(@klass, @relation.
|
32
|
-
end
|
33
|
-
|
34
|
-
def where(conditions)
|
35
|
-
Relation.new(@klass, @relation.where(conditions))
|
36
|
+
def where(*conditions)
|
37
|
+
Relation.new(@klass, @relation.where(*conditions))
|
36
38
|
end
|
37
39
|
|
38
|
-
def select(selects)
|
39
|
-
Relation.new(@klass, @relation.project(selects))
|
40
|
+
def select(*selects)
|
41
|
+
Relation.new(@klass, @relation.project(*selects))
|
40
42
|
end
|
41
43
|
|
42
44
|
def group(groups)
|
data/lib/cramp/model/status.rb
CHANGED
data/lib/cramp/model.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'cramp'
|
1
2
|
require 'cramp/model/evented_mysql'
|
2
3
|
require 'cramp/model/emysql_ext'
|
3
4
|
|
@@ -25,6 +26,14 @@ module Cramp
|
|
25
26
|
Arel::Table.engine = Cramp::Model::Engine.new(settings)
|
26
27
|
end
|
27
28
|
|
29
|
+
def self.select(query, callback = nil, &block)
|
30
|
+
callback ||= block
|
31
|
+
|
32
|
+
EventedMysql.select(query) do |rows|
|
33
|
+
callback.arity == 1 ? callback.call(rows) : callback.call if callback
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
28
37
|
end
|
29
38
|
end
|
30
39
|
|
data/lib/cramp.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'eventmachine'
|
2
|
+
EM.epoll
|
2
3
|
|
3
4
|
require 'active_support'
|
4
|
-
require 'active_support/concern'
|
5
5
|
require 'active_support/core_ext'
|
6
|
+
require 'active_support/concern'
|
7
|
+
|
8
|
+
require 'cramp/core_ext'
|
6
9
|
|
7
10
|
module Cramp
|
8
|
-
VERSION = '0.
|
11
|
+
VERSION = '0.6'
|
9
12
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cramp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "0.
|
4
|
+
version: "0.6"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pratik Naik
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-07 00:00:00 +05:30
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -93,9 +93,16 @@ extra_rdoc_files: []
|
|
93
93
|
files:
|
94
94
|
- README
|
95
95
|
- MIT-LICENSE
|
96
|
-
- lib/cramp/controller/
|
96
|
+
- lib/cramp/controller/abstract.rb
|
97
|
+
- lib/cramp/controller/action.rb
|
97
98
|
- lib/cramp/controller/body.rb
|
99
|
+
- lib/cramp/controller/callbacks.rb
|
100
|
+
- lib/cramp/controller/keep_connection_alive.rb
|
101
|
+
- lib/cramp/controller/periodic_timer.rb
|
102
|
+
- lib/cramp/controller/rendering.rb
|
103
|
+
- lib/cramp/controller/test_case.rb
|
98
104
|
- lib/cramp/controller.rb
|
105
|
+
- lib/cramp/core_ext.rb
|
99
106
|
- lib/cramp/model/arel_monkey_patches.rb
|
100
107
|
- lib/cramp/model/attribute.rb
|
101
108
|
- lib/cramp/model/attribute_methods.rb
|
@@ -1,114 +0,0 @@
|
|
1
|
-
module Cramp
|
2
|
-
module Controller
|
3
|
-
class Base
|
4
|
-
ASYNC_RESPONSE = [-1, {}, []]
|
5
|
-
|
6
|
-
DEFAULT_STATUS = 200
|
7
|
-
DEFAULT_HEADERS = { 'Content-Type' => 'text/html' }
|
8
|
-
|
9
|
-
def self.call(env)
|
10
|
-
controller = new(env).process
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.set_default_response(status = 200, headers = DEFAULT_HEADERS)
|
14
|
-
@@default_status = 200
|
15
|
-
@@default_headers = headers
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.default_status
|
19
|
-
defined?(@@default_status) ? @@default_status : DEFAULT_STATUS
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.default_headers
|
23
|
-
defined?(@@default_headers) ? @@default_headers : DEFAULT_HEADERS
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.periodic_timer(method, options = {})
|
27
|
-
@@periodic_timers ||= []
|
28
|
-
@@periodic_timers << [method, options]
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.periodic_timers
|
32
|
-
defined?(@@periodic_timers) ? @@periodic_timers : []
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.keep_connection_alive(options = {})
|
36
|
-
options = { :every => 30 }.merge(options)
|
37
|
-
periodic_timer :keep_connection_alive, options
|
38
|
-
end
|
39
|
-
|
40
|
-
def initialize(env)
|
41
|
-
@env = env
|
42
|
-
@timers = []
|
43
|
-
end
|
44
|
-
|
45
|
-
def process
|
46
|
-
EM.next_tick { before_start }
|
47
|
-
ASYNC_RESPONSE
|
48
|
-
end
|
49
|
-
|
50
|
-
def request
|
51
|
-
@request ||= Rack::Request.new(@env)
|
52
|
-
end
|
53
|
-
|
54
|
-
def params
|
55
|
-
@params ||= @env['usher.params']
|
56
|
-
end
|
57
|
-
|
58
|
-
def render(body)
|
59
|
-
@body.call(body)
|
60
|
-
end
|
61
|
-
|
62
|
-
def send_initial_response(response_status, response_headers, response_body)
|
63
|
-
EM.next_tick { @env['async.callback'].call [response_status, response_headers, response_body] }
|
64
|
-
end
|
65
|
-
|
66
|
-
def finish
|
67
|
-
EM.next_tick { @body.succeed }
|
68
|
-
end
|
69
|
-
|
70
|
-
def before_start
|
71
|
-
continue
|
72
|
-
end
|
73
|
-
|
74
|
-
def halt(status, headers = self.class.default_headers, halt_body = '')
|
75
|
-
send_initial_response(status, headers, halt_body)
|
76
|
-
end
|
77
|
-
|
78
|
-
def continue
|
79
|
-
init_async_body
|
80
|
-
send_initial_response(self.class.default_status, self.class.default_headers, @body)
|
81
|
-
|
82
|
-
EM.next_tick { start_periodic_timers }
|
83
|
-
EM.next_tick { start } if respond_to?(:start)
|
84
|
-
end
|
85
|
-
|
86
|
-
def init_async_body
|
87
|
-
@body = Body.new
|
88
|
-
@body.callback { on_finish }
|
89
|
-
@body.errback { on_finish }
|
90
|
-
|
91
|
-
@body.callback { stop_periodic_timers }
|
92
|
-
@body.errback { stop_periodic_timers }
|
93
|
-
end
|
94
|
-
|
95
|
-
def start_periodic_timers
|
96
|
-
self.class.periodic_timers.each do |method, options|
|
97
|
-
@timers << EventMachine::PeriodicTimer.new(options[:every] || 1) { send(method) }
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def stop_periodic_timers
|
102
|
-
@timers.each {|t| t.cancel }
|
103
|
-
end
|
104
|
-
|
105
|
-
def on_finish
|
106
|
-
end
|
107
|
-
|
108
|
-
def keep_connection_alive
|
109
|
-
render " "
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|