skyline 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/LICENSE +22 -0
- data/README.md +2 -4
- data/lib/skyline.rb +29 -1
- data/lib/skyline/abstract_action.rb +114 -0
- data/lib/skyline/body.rb +46 -0
- data/lib/skyline/callbacks.rb +91 -0
- data/lib/skyline/exception_handler.rb +25 -0
- data/lib/skyline/fiber_pool.rb +47 -0
- data/lib/skyline/version.rb +1 -1
- data/lib/vendor/fiber_pool.rb +85 -0
- data/skyline.gemspec +1 -0
- metadata +22 -2
- data/LICENSE.txt +0 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2b00ff6f35a17d706ed0a7f323bc732d9c6c4e6f
|
|
4
|
+
data.tar.gz: 85b6accc874c6d82e51eec06aa11f91f79cb2caa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1f4cafee8c8ba8049832a674817b195495a3b28b6b3fcf28cc593bdd4acbfb0244044769258dc01e4f72fa40122f5bb6ce6c5c6d7202b8bbba5fcfda636c60b8
|
|
7
|
+
data.tar.gz: 1ffb68c85be9dd95b16ed3018c5afed1542dd9a1b03846f70372e8587a63ea4000c0a19f9d336fdf3b0f384a3b00986da931d672d4b00635ce7eec6ce91caaa9
|
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2015 sickate
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
data/README.md
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# Skyline
|
|
2
|
-
|
|
3
|
-
TODO: Write a gem description
|
|
2
|
+
A minimal Event-Driven HTTP server which stolen from Cramp. (https://github.com/lifo/cramp)
|
|
4
3
|
|
|
5
4
|
## Installation
|
|
6
5
|
|
|
@@ -19,8 +18,7 @@ Or install it yourself as:
|
|
|
19
18
|
$ gem install skyline
|
|
20
19
|
|
|
21
20
|
## Usage
|
|
22
|
-
|
|
23
|
-
TODO: Write usage instructions here
|
|
21
|
+
TODO
|
|
24
22
|
|
|
25
23
|
## Contributing
|
|
26
24
|
|
data/lib/skyline.rb
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
require "skyline/version"
|
|
2
2
|
|
|
3
|
+
require 'eventmachine'
|
|
4
|
+
require 'active_support'
|
|
5
|
+
require 'active_support/core_ext/class/attribute'
|
|
6
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
|
7
|
+
require 'active_support/core_ext/module/aliasing'
|
|
8
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
|
9
|
+
require 'active_support/core_ext/kernel/reporting'
|
|
10
|
+
require 'active_support/concern'
|
|
11
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
|
12
|
+
require 'active_support/core_ext/hash/except'
|
|
13
|
+
require 'rack'
|
|
14
|
+
require 'faye/websocket'
|
|
15
|
+
|
|
16
|
+
EM.epoll
|
|
17
|
+
|
|
18
|
+
begin
|
|
19
|
+
require 'fiber'
|
|
20
|
+
require File.join(File.dirname(__FILE__), 'fiber_pool')
|
|
21
|
+
rescue LoadError
|
|
22
|
+
# No fibers available!
|
|
23
|
+
end
|
|
24
|
+
|
|
3
25
|
module Skyline
|
|
4
|
-
|
|
26
|
+
mattr_accessor :logger
|
|
27
|
+
|
|
28
|
+
autoload :AbstractAction, 'skyline/action'
|
|
29
|
+
autoload :Body, 'skyline/body'
|
|
30
|
+
autoload :Callbacks, 'skyline/callbacks'
|
|
31
|
+
autoload :FiberPool, 'skyline/fiber_pool'
|
|
32
|
+
autoload :ExceptionHandler, 'skyline/exception_handler'
|
|
5
33
|
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require 'active_support/core_ext/hash/keys'
|
|
2
|
+
|
|
3
|
+
module Skyline
|
|
4
|
+
class AbstractAction
|
|
5
|
+
include Callbacks
|
|
6
|
+
include FiberPool
|
|
7
|
+
|
|
8
|
+
AsyncResponse = [-1, {}, []].freeze
|
|
9
|
+
|
|
10
|
+
class_attribute :transport
|
|
11
|
+
class_attribute :logger
|
|
12
|
+
|
|
13
|
+
self.transport = :regular
|
|
14
|
+
|
|
15
|
+
class << self
|
|
16
|
+
def call(env)
|
|
17
|
+
new(env).process
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def initialize(env)
|
|
22
|
+
@env = env
|
|
23
|
+
@finished = false
|
|
24
|
+
|
|
25
|
+
@_state = :init
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def process
|
|
29
|
+
EM.next_tick { before_start }
|
|
30
|
+
AsyncResponse
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
protected
|
|
34
|
+
|
|
35
|
+
def render(body, *args)
|
|
36
|
+
@body.call(body)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def encode(string, encoding = 'UTF-8')
|
|
40
|
+
string.respond_to?(:force_encoding) ? string.force_encoding(encoding) : string
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def continue
|
|
44
|
+
init_async_body
|
|
45
|
+
send_headers
|
|
46
|
+
|
|
47
|
+
@_state = :started
|
|
48
|
+
EM.next_tick { on_start }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def send_headers
|
|
52
|
+
status, headers = build_headers
|
|
53
|
+
send_initial_response(status, headers, @body)
|
|
54
|
+
rescue StandardError, LoadError, SyntaxError => exception
|
|
55
|
+
handle_exception(exception)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def build_headers
|
|
59
|
+
status, headers = respond_to?(:respond_with, true) ? respond_with.dup : [200, {'Content-Type' => 'text/html'}]
|
|
60
|
+
headers['Connection'] ||= 'keep-alive'
|
|
61
|
+
[status, headers]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def init_async_body
|
|
65
|
+
@body = Body.new
|
|
66
|
+
|
|
67
|
+
if self.class.on_finish_callbacks.any?
|
|
68
|
+
@body.callback { on_finish }
|
|
69
|
+
@body.errback { on_finish }
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def finished?
|
|
74
|
+
!!@finished
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def finish
|
|
78
|
+
@_state = :finishing
|
|
79
|
+
@body.succeed if is_finishable?
|
|
80
|
+
ensure
|
|
81
|
+
@_state = :finished
|
|
82
|
+
@finished = true
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def send_initial_response(response_status, response_headers, response_body)
|
|
86
|
+
send_response(response_status, response_headers, response_body)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def halt(status, headers = {}, halt_body = '')
|
|
90
|
+
send_response(status, headers, [halt_body])
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def send_response(response_status, response_headers, response_body)
|
|
94
|
+
@env['async.callback'].call [response_status, response_headers, response_body]
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def request
|
|
98
|
+
@request ||= Rack::Request.new(@env)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def params
|
|
102
|
+
@params ||= request.params.update(route_params).symbolize_keys
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def route_params
|
|
106
|
+
@env['router.params'] || {}
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def is_finishable?
|
|
110
|
+
!finished? && @body && !@body.closed?
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
end
|
|
114
|
+
end
|
data/lib/skyline/body.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Skyline
|
|
2
|
+
class Body
|
|
3
|
+
include EventMachine::Deferrable
|
|
4
|
+
|
|
5
|
+
def initialize
|
|
6
|
+
@queue = []
|
|
7
|
+
|
|
8
|
+
# Make sure to flush out the queue before closing the connection
|
|
9
|
+
callback { flush }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call(body)
|
|
13
|
+
@queue << body
|
|
14
|
+
schedule_dequeue
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def each &blk
|
|
18
|
+
@body_callback = blk
|
|
19
|
+
schedule_dequeue
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def closed?
|
|
23
|
+
@deferred_status != :unknown
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def flush
|
|
27
|
+
return unless @body_callback
|
|
28
|
+
|
|
29
|
+
until @queue.empty?
|
|
30
|
+
Array(@queue.shift).each {|chunk| @body_callback.call(chunk) }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def schedule_dequeue
|
|
35
|
+
return unless @body_callback
|
|
36
|
+
|
|
37
|
+
EventMachine.next_tick do
|
|
38
|
+
next unless body = @queue.shift
|
|
39
|
+
|
|
40
|
+
Array(body).each {|chunk| @body_callback.call(chunk) }
|
|
41
|
+
schedule_dequeue unless @queue.empty?
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module Skyline
|
|
2
|
+
module Callbacks
|
|
3
|
+
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
class_attribute :before_start_callbacks, :on_finish_callbacks, :on_start_callback, :on_data_callbacks, :instance_reader => false
|
|
8
|
+
|
|
9
|
+
self.before_start_callbacks = []
|
|
10
|
+
self.on_finish_callbacks = []
|
|
11
|
+
self.on_start_callback = []
|
|
12
|
+
self.on_data_callbacks = []
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module ClassMethods
|
|
16
|
+
def before_start(*methods)
|
|
17
|
+
self.before_start_callbacks += methods
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def on_finish(*methods)
|
|
21
|
+
self.on_finish_callbacks += methods
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def on_start(*methods)
|
|
25
|
+
self.on_start_callback += methods
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def on_data(*methods)
|
|
29
|
+
self.on_data_callbacks += methods
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def before_start(n = 0)
|
|
34
|
+
if callback = self.class.before_start_callbacks[n]
|
|
35
|
+
callback_wrapper { send(callback) { before_start(n+1) } }
|
|
36
|
+
else
|
|
37
|
+
continue
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def on_start
|
|
42
|
+
callback_wrapper { start } if respond_to?(:start)
|
|
43
|
+
|
|
44
|
+
self.class.on_start_callback.each do |callback|
|
|
45
|
+
callback_wrapper { send(callback) unless @finished }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def on_finish
|
|
50
|
+
self.class.on_finish_callbacks.each do |callback|
|
|
51
|
+
callback_wrapper { send(callback) }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def callback_wrapper
|
|
56
|
+
EM.next_tick do
|
|
57
|
+
begin
|
|
58
|
+
yield
|
|
59
|
+
rescue StandardError, LoadError, SyntaxError => exception
|
|
60
|
+
handle_exception(exception)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
protected
|
|
66
|
+
|
|
67
|
+
def _invoke_data_callbacks(message)
|
|
68
|
+
self.class.on_data_callbacks.each do |callback|
|
|
69
|
+
callback_wrapper { send(callback, message) }
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def handle_exception(exception)
|
|
74
|
+
handler = ExceptionHandler.new(@env, exception)
|
|
75
|
+
|
|
76
|
+
# Log the exception
|
|
77
|
+
exception_body = handler.dump_exception
|
|
78
|
+
Skyline.logger ? Skyline.logger.error(exception_body) : $stderr.puts(exception_body)
|
|
79
|
+
|
|
80
|
+
case @_state
|
|
81
|
+
when :init
|
|
82
|
+
halt 500, {"Content-Type" => 'text/html'}, ENV['RACK_ENV'] == 'development' ? handler.pretty : 'Something went wrong'
|
|
83
|
+
when :started
|
|
84
|
+
halt 500, {"Content-Type" => 'text/html'}, ENV['RACK_ENV'] == 'development' ? handler.pretty : 'Something went wrong'
|
|
85
|
+
else
|
|
86
|
+
finish
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Skyline
|
|
2
|
+
class ExceptionHandler
|
|
3
|
+
|
|
4
|
+
attr_reader :env, :exception
|
|
5
|
+
|
|
6
|
+
def initialize(env, exception)
|
|
7
|
+
@env = env
|
|
8
|
+
@exception = exception
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def dump_exception
|
|
12
|
+
string = "#{exception.class}: #{exception.message}\n"
|
|
13
|
+
string << exception.backtrace.map { |l| "\t#{l}" }.join("\n")
|
|
14
|
+
string
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def pretty
|
|
18
|
+
dump_exception
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def h
|
|
22
|
+
dump_exception
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Skyline
|
|
2
|
+
module FiberPool
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
class_attribute :fiber_pool
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module ClassMethods
|
|
10
|
+
def use_fiber_pool(options = {})
|
|
11
|
+
unless defined?(::FiberPool)
|
|
12
|
+
raise "Fiber support is only available for Rubies >= 1.9.2"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
self.fiber_pool = ::FiberPool.new(options[:size] || 100)
|
|
16
|
+
yield self.fiber_pool if block_given?
|
|
17
|
+
include UsesFiberPool
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
module UsesFiberPool
|
|
22
|
+
# Overrides wrapper methods to run callbacks in a fiber
|
|
23
|
+
|
|
24
|
+
def callback_wrapper
|
|
25
|
+
self.fiber_pool.spawn do
|
|
26
|
+
begin
|
|
27
|
+
yield
|
|
28
|
+
rescue StandardError, LoadError, SyntaxError => exception
|
|
29
|
+
handle_exception(exception)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def timer_method_wrapper(method)
|
|
35
|
+
self.fiber_pool.spawn do
|
|
36
|
+
begin
|
|
37
|
+
send(method)
|
|
38
|
+
rescue StandardError, LoadError, SyntaxError => exception
|
|
39
|
+
handle_exception(exception)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/skyline/version.rb
CHANGED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Author:: Mohammad A. Ali (mailto:oldmoe@gmail.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2008 eSpace, Inc.
|
|
3
|
+
# License:: Distributes under the same terms as Ruby
|
|
4
|
+
|
|
5
|
+
require 'fiber'
|
|
6
|
+
|
|
7
|
+
class Fiber
|
|
8
|
+
|
|
9
|
+
#Attribute Reference--Returns the value of a fiber-local variable, using
|
|
10
|
+
#either a symbol or a string name. If the specified variable does not exist,
|
|
11
|
+
#returns nil.
|
|
12
|
+
def [](key)
|
|
13
|
+
local_fiber_variables[key]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
#Attribute Assignment--Sets or creates the value of a fiber-local variable,
|
|
17
|
+
#using either a symbol or a string. See also Fiber#[].
|
|
18
|
+
def []=(key,value)
|
|
19
|
+
local_fiber_variables[key] = value
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
protected
|
|
23
|
+
|
|
24
|
+
def local_fiber_variables
|
|
25
|
+
@local_fiber_variables ||= {}
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class FiberPool
|
|
30
|
+
|
|
31
|
+
# gives access to the currently free fibers
|
|
32
|
+
attr_reader :fibers
|
|
33
|
+
attr_reader :busy_fibers
|
|
34
|
+
|
|
35
|
+
# Code can register a proc with this FiberPool to be called
|
|
36
|
+
# every time a Fiber is finished. Good for releasing resources
|
|
37
|
+
# like ActiveRecord database connections.
|
|
38
|
+
attr_accessor :generic_callbacks
|
|
39
|
+
|
|
40
|
+
# Prepare a list of fibers that are able to run different blocks of code
|
|
41
|
+
# every time. Once a fiber is done with its block, it attempts to fetch
|
|
42
|
+
# another one from the queue
|
|
43
|
+
def initialize(count = 100)
|
|
44
|
+
@fibers,@busy_fibers,@queue,@generic_callbacks = [],{},[],[]
|
|
45
|
+
count.times do |i|
|
|
46
|
+
fiber = Fiber.new do |block|
|
|
47
|
+
loop do
|
|
48
|
+
block.call
|
|
49
|
+
|
|
50
|
+
# callbacks are called in a reverse order, much like c++ destructor
|
|
51
|
+
Fiber.current[:callbacks].pop.call while Fiber.current[:callbacks].length > 0
|
|
52
|
+
generic_callbacks.each do |cb|
|
|
53
|
+
cb.call
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
if @queue.any?
|
|
57
|
+
block = @queue.shift
|
|
58
|
+
else
|
|
59
|
+
@busy_fibers.delete(Fiber.current.object_id)
|
|
60
|
+
@fibers.unshift Fiber.current
|
|
61
|
+
block = Fiber.yield
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
fiber[:callbacks] = []
|
|
67
|
+
fiber[:em_keys] = []
|
|
68
|
+
@fibers << fiber
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# If there is an available fiber use it, otherwise, leave it to linger
|
|
73
|
+
# in a queue
|
|
74
|
+
def spawn(&block)
|
|
75
|
+
if fiber = @fibers.shift
|
|
76
|
+
fiber[:callbacks] = []
|
|
77
|
+
@busy_fibers[fiber.object_id] = fiber
|
|
78
|
+
fiber.resume(block)
|
|
79
|
+
else
|
|
80
|
+
@queue << block
|
|
81
|
+
end
|
|
82
|
+
self # we are keen on hiding our queue
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
data/skyline.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: skyline
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- sickcate
|
|
@@ -38,6 +38,20 @@ dependencies:
|
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '10.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
41
55
|
description: It's mainly stolen from Rack server "Cramp".
|
|
42
56
|
email:
|
|
43
57
|
- iamzhutuo@gmail.com
|
|
@@ -47,11 +61,17 @@ extra_rdoc_files: []
|
|
|
47
61
|
files:
|
|
48
62
|
- ".gitignore"
|
|
49
63
|
- Gemfile
|
|
50
|
-
- LICENSE
|
|
64
|
+
- LICENSE
|
|
51
65
|
- README.md
|
|
52
66
|
- Rakefile
|
|
53
67
|
- lib/skyline.rb
|
|
68
|
+
- lib/skyline/abstract_action.rb
|
|
69
|
+
- lib/skyline/body.rb
|
|
70
|
+
- lib/skyline/callbacks.rb
|
|
71
|
+
- lib/skyline/exception_handler.rb
|
|
72
|
+
- lib/skyline/fiber_pool.rb
|
|
54
73
|
- lib/skyline/version.rb
|
|
74
|
+
- lib/vendor/fiber_pool.rb
|
|
55
75
|
- skyline.gemspec
|
|
56
76
|
homepage: ''
|
|
57
77
|
licenses:
|
data/LICENSE.txt
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
Copyright (c) 2015 sickcate
|
|
2
|
-
|
|
3
|
-
MIT License
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
-
a copy of this software and associated documentation files (the
|
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
-
the following conditions:
|
|
12
|
-
|
|
13
|
-
The above copyright notice and this permission notice shall be
|
|
14
|
-
included in all copies or substantial portions of the Software.
|
|
15
|
-
|
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|