crampy 0.15.3

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.
@@ -0,0 +1,56 @@
1
+ module Cramp
2
+ module PeriodicTimer
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ # was class_inheritable_accessor
8
+ class_attribute :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
+ protected
24
+
25
+ def continue
26
+ super
27
+ start_periodic_timers
28
+ end
29
+
30
+ def init_async_body
31
+ super
32
+
33
+ if self.class.periodic_timers.any?
34
+ @body.callback { stop_periodic_timers }
35
+ @body.errback { stop_periodic_timers }
36
+ end
37
+ end
38
+
39
+ def start_periodic_timers
40
+ self.class.periodic_timers.each do |method, options|
41
+ @timers << EventMachine::PeriodicTimer.new(options[:every] || 1) { timer_method_wrapper(method) unless @finished }
42
+ end
43
+ end
44
+
45
+ def stop_periodic_timers
46
+ @timers.each {|t| t.cancel }
47
+ end
48
+
49
+ def timer_method_wrapper(method)
50
+ send(method)
51
+ rescue StandardError, LoadError, SyntaxError => exception
52
+ handle_exception(exception)
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,11 @@
1
+ module Cramp
2
+ module Rendering
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ def render(body)
7
+ @body.call(body)
8
+ end
9
+
10
+ end
11
+ end
data/lib/cramp/sse.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Cramp
2
+ class SSE < Action
3
+ self.transport = :sse
4
+ end
5
+ end
@@ -0,0 +1,58 @@
1
+ require 'active_support'
2
+ require 'active_support/test_case'
3
+
4
+ module Cramp
5
+ class TestCase < ::ActiveSupport::TestCase
6
+
7
+ setup :create_request
8
+
9
+ def create_request
10
+ @request = Rack::MockRequest.new(app)
11
+ end
12
+
13
+ def get(path, options = {}, headers = {}, &block)
14
+ callback = options.delete(:callback) || block
15
+ headers = headers.merge('async.callback' => callback)
16
+
17
+ EM.run do
18
+ catch(:async) { @request.get(path, headers) }
19
+ end
20
+ end
21
+
22
+ def get_body(path, options = {}, headers = {}, &block)
23
+ callback = options.delete(:callback) || block
24
+ response_callback = proc {|response| response[-1].each {|chunk| callback.call(chunk) } }
25
+ headers = headers.merge('async.callback' => response_callback)
26
+
27
+ EM.run do
28
+ catch(:async) { @request.get(path, headers) }
29
+ end
30
+ end
31
+
32
+ def get_body_chunks(path, options = {}, headers = {}, &block)
33
+ callback = options.delete(:callback) || block
34
+ count = options.delete(:count) || 1
35
+
36
+ stopping = false
37
+ chunks = []
38
+
39
+ get_body(path, options, headers) do |body_chunk|
40
+ chunks << body_chunk unless stopping
41
+
42
+ if chunks.count >= count
43
+ stopping = true
44
+ callback.call(chunks) if callback
45
+ EM.next_tick { EM.stop }
46
+ end
47
+ end
48
+ end
49
+
50
+ def app
51
+ raise "Please define a method called 'app' returning an async Rack Application"
52
+ end
53
+
54
+ def stop
55
+ EM.stop
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ module Cramp
2
+ VERSION = '0.15.3'
3
+ end
@@ -0,0 +1,13 @@
1
+ module Cramp
2
+ class Websocket < Action
3
+ self.transport = :websocket
4
+
5
+ class << self
6
+ def backend=(backend)
7
+ raise "Websocket backend #{backend} is unknown" unless [:thin, :rainbows].include?(backend.to_sym)
8
+ Faye::WebSocket.load_adapter(backend.to_s)
9
+ end
10
+ end
11
+
12
+ end
13
+ end
data/lib/cramp.rb ADDED
@@ -0,0 +1,47 @@
1
+ require 'eventmachine'
2
+ # this shoud be called before reactor start, otherwise EM will silently ignore it
3
+ EM.epoll
4
+
5
+ require 'active_support'
6
+ require 'active_support/core_ext/class/attribute'
7
+ #require 'active_support/core_ext/class/inheritable_attributes'
8
+ require 'active_support/core_ext/class/attribute_accessors'
9
+ require 'active_support/core_ext/module/aliasing'
10
+ require 'active_support/core_ext/module/attribute_accessors'
11
+ require 'active_support/core_ext/kernel/reporting'
12
+ require 'active_support/concern'
13
+ require 'active_support/core_ext/hash/indifferent_access'
14
+ require 'active_support/core_ext/hash/except'
15
+ require 'active_support/buffered_logger'
16
+
17
+ require 'rack'
18
+ require 'faye/websocket'
19
+
20
+ begin
21
+ require 'fiber'
22
+ require File.join(File.dirname(__FILE__), 'vendor/fiber_pool')
23
+ rescue LoadError
24
+ # No fibers available!
25
+ end
26
+
27
+ module Cramp
28
+ ROOT = File.expand_path(File.dirname(__FILE__))
29
+ require "#{Cramp::ROOT}/cramp/version"
30
+
31
+ mattr_accessor :logger
32
+
33
+ autoload :Action, "cramp/action"
34
+ autoload :Websocket, "cramp/websocket"
35
+ autoload :WebsocketExtension, "cramp/websocket/extension"
36
+ autoload :Protocol10FrameParser, "cramp/websocket/protocol10_frame_parser"
37
+ autoload :SSE, "cramp/sse"
38
+ autoload :LongPolling, "cramp/long_polling"
39
+ autoload :Body, "cramp/body"
40
+ autoload :PeriodicTimer, "cramp/periodic_timer"
41
+ autoload :KeepConnectionAlive, "cramp/keep_connection_alive"
42
+ autoload :Abstract, "cramp/abstract"
43
+ autoload :Callbacks, "cramp/callbacks"
44
+ autoload :FiberPool, "cramp/fiber_pool"
45
+ autoload :ExceptionHandler, "cramp/exception_handler"
46
+ autoload :TestCase, "cramp/test_case"
47
+ end
data/lib/crampy.rb ADDED
@@ -0,0 +1,4 @@
1
+ require File.expand_path('../cramp', __FILE__)
2
+
3
+ # no namespace change yet
4
+ Crampy = Cramp
@@ -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
+ private
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
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: crampy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.15.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Pratik Naik
9
+ - Vasily Fedoseyev
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-06-12 00:00:00.000000000Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ requirement: &70186850572180 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '3.2'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *70186850572180
26
+ - !ruby/object:Gem::Dependency
27
+ name: rack
28
+ requirement: &70186850570900 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *70186850570900
37
+ - !ruby/object:Gem::Dependency
38
+ name: eventmachine
39
+ requirement: &70186850569540 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: 1.0.0.beta.3
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *70186850569540
48
+ - !ruby/object:Gem::Dependency
49
+ name: faye-websocket
50
+ requirement: &70186850567380 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: '0.3'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *70186850567380
59
+ - !ruby/object:Gem::Dependency
60
+ name: thor
61
+ requirement: &70186850565720 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: '0.14'
67
+ type: :runtime
68
+ prerelease: false
69
+ version_requirements: *70186850565720
70
+ description: Crampy is a fork of Cramp, a framework for developing asynchronous web
71
+ applications.
72
+ email:
73
+ - vasilyfedoseyev@gmail.com
74
+ executables:
75
+ - cramp
76
+ extensions: []
77
+ extra_rdoc_files: []
78
+ files:
79
+ - MIT-LICENSE
80
+ - lib/cramp/abstract.rb
81
+ - lib/cramp/action.rb
82
+ - lib/cramp/body.rb
83
+ - lib/cramp/callbacks.rb
84
+ - lib/cramp/exception_handler.rb
85
+ - lib/cramp/fiber_pool.rb
86
+ - lib/cramp/generators/application.rb
87
+ - lib/cramp/generators/templates/application/app/actions/home_action.rb
88
+ - lib/cramp/generators/templates/application/application.rb
89
+ - lib/cramp/generators/templates/application/config/database.yml
90
+ - lib/cramp/generators/templates/application/config/routes.rb
91
+ - lib/cramp/generators/templates/application/config.ru
92
+ - lib/cramp/generators/templates/application/Gemfile
93
+ - lib/cramp/keep_connection_alive.rb
94
+ - lib/cramp/long_polling.rb
95
+ - lib/cramp/periodic_timer.rb
96
+ - lib/cramp/rendering.rb
97
+ - lib/cramp/sse.rb
98
+ - lib/cramp/test_case.rb
99
+ - lib/cramp/version.rb
100
+ - lib/cramp/websocket.rb
101
+ - lib/cramp.rb
102
+ - lib/crampy.rb
103
+ - lib/vendor/fiber_pool.rb
104
+ - bin/cramp
105
+ homepage: https://github.com/Vasfed/cramp
106
+ licenses: []
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ! '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ! '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubyforge_project:
125
+ rubygems_version: 1.8.15
126
+ signing_key:
127
+ specification_version: 3
128
+ summary: Asynchronous web framework.
129
+ test_files: []
130
+ has_rdoc: false