fibre 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8fabc7b72080a5a72b9c4f02e298546228dfebca
4
+ data.tar.gz: ffb6409b8cb5e104792c007ea293ec28c20bbc5b
5
+ SHA512:
6
+ metadata.gz: 6a47d2f626884a4efcd6a589e9d255b3305432884a044239e8c08b531773299fa0e20e2d92ae4945d2a2c4b723128da94ae386f4b1baff8147e99197bc923c98
7
+ data.tar.gz: db6e15c5b1f7882db1b0212d2fb5e5b1c39a6f32513394ead72cf17670c142999ae5e0e67dff9fd0a81982337676a71cec1268d4a5079d7bafd2264911a44f3e
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fibre.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 che
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.
@@ -0,0 +1,46 @@
1
+ # Fibre
2
+
3
+ Fibre - fiber pool with events
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'fibre'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install fibre
20
+
21
+ Initialize pool:
22
+
23
+ Fibre.pool_size = 10
24
+
25
+ ## Usage
26
+
27
+ ```ruby
28
+ Fibre.pool_size = 10
29
+ Fibre.pool.checkout do
30
+ puts "runned in fiber"
31
+ end
32
+ # some fiber raised exception
33
+ using EventObject
34
+ Fibre.pool.on :error do |e|
35
+ puts e.to_s
36
+ exit
37
+ end
38
+ ```
39
+
40
+ ## Contributing
41
+
42
+ 1. Fork it ( https://github.com/chelovekov/fibre/fork )
43
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
44
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
45
+ 4. Push to the branch (`git push origin my-new-feature`)
46
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'fibre/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "fibre"
8
+ spec.version = Fibre::VERSION
9
+ spec.authors = ["che"]
10
+ spec.email = ["max@kupibilet.ru"]
11
+ spec.summary = %q{Fibre - fiber pool, mock and scoping fibres}
12
+ #spec.description = %q{TODO: Write a longer description. Optional.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.required_ruby_version = '>= 2.1.0'
22
+ spec.required_rubygems_version = '>= 2.3.0'
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.6"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0.0"
27
+
28
+ spec.add_dependency "event_object", "~> 0.9"
29
+ end
@@ -0,0 +1,31 @@
1
+ require "event_object"
2
+ require "fibre/version"
3
+ require "fibre/core_ext/fiber"
4
+
5
+ module Fibre
6
+ autoload :FiberPool, 'fibre/fiber_pool'
7
+ autoload :Mock, 'fibre/mock'
8
+ autoload :Scope, 'fibre/scope'
9
+
10
+ module Rack
11
+ autoload :FiberPool, 'fibre/rack/fiber_pool'
12
+ end
13
+
14
+ # Configuration module
15
+
16
+ extend self
17
+
18
+ # Fiber.root - root fiber
19
+ attr_accessor :root
20
+ self.root = Fiber.current
21
+
22
+ # Pool size can be set before pool initialized
23
+ attr_accessor :pool_size
24
+ self.pool_size = 20
25
+
26
+ # Initialize with default pool_size
27
+ attr_writer :pool
28
+ def pool
29
+ @pool ||= FiberPool.new(pool_size)
30
+ end
31
+ end
@@ -0,0 +1,57 @@
1
+ require 'fiber'
2
+
3
+ #
4
+ # Fiber.sync do |fiber|
5
+ # fiber.resume response
6
+ # fiber.leave StandardError, "Something"
7
+ # end
8
+ class Fiber
9
+
10
+ def attributes
11
+ @attributes ||= {}
12
+ end
13
+
14
+ def root?
15
+ self.eql? Fibre.root
16
+ end
17
+
18
+ def [](key)
19
+ attributes[key]
20
+ end
21
+
22
+ def []=(key,value)
23
+ attributes[key] = value
24
+ end
25
+
26
+ class <<self
27
+
28
+ def scope(*a, &b)
29
+ Fiber::Scope.scope(*a, &b)
30
+ end
31
+
32
+ def sync(*a, &b)
33
+ Fiber::Scope.scope? ? Fiber::Scope.sync(*a, &b) : sync_it(*a, &b)
34
+ end
35
+
36
+ # raise exception if we catch exception
37
+ def yield!
38
+ Fiber.yield.tap do |y|
39
+ raise y if y.is_a?(Exception)
40
+ end
41
+ end
42
+
43
+ #
44
+ # Fiber.sync do |fiber|
45
+ # fiber.resume # ...
46
+ # end
47
+ #
48
+ def sync_it
49
+ yield(Fiber.current) if block_given?
50
+ Fiber.yield!
51
+ end
52
+ end
53
+
54
+ def leave(exception, message=nil)
55
+ resume exception.new(message)
56
+ end
57
+ end
@@ -0,0 +1,92 @@
1
+ #
2
+ # Fiber pool
3
+ #
4
+ # Example,
5
+ # using EventObject
6
+ # pool = Fibre::FiberPool.new(10)
7
+ # pool.checkout do
8
+ # puts "runned in fiber"
9
+ # end
10
+ #
11
+ # # some fiber raised exception
12
+ # pool.on :error do |e|
13
+ # puts e.to_s
14
+ # end
15
+
16
+ module Fibre
17
+ using EventObject
18
+
19
+ class FiberPool
20
+ events :error, :before, :after
21
+
22
+ # Initialize fibers pool
23
+ def initialize(size)
24
+ @pool = size.times.collect { ::Fiber.new(&self.method(:fiber_entry)) }
25
+ @reserved = {}
26
+ @queue = []
27
+ end
28
+
29
+ # Check-out fiber from pool
30
+ def checkout(&b)
31
+ spec = { block: b, parent: ::Fiber.current }
32
+
33
+ if @pool.empty?
34
+ raise "fiber queue overflow" if @queue.size > MAX_POOL_QUEUE_SIZE
35
+ @queue.push spec
36
+ return
37
+ end
38
+
39
+ @pool.shift.tap do |fiber|
40
+ @reserved[fiber.object_id] = fiber
41
+ fiber.resume(spec)
42
+ end
43
+
44
+ self
45
+ end
46
+
47
+ # Free pool size
48
+ def size
49
+ @pool.size
50
+ end
51
+
52
+ def reserved
53
+ @reserved
54
+ end
55
+
56
+ def queue
57
+ @queue
58
+ end
59
+
60
+ private
61
+
62
+ # entrypoint for all fibers
63
+ def fiber_entry(spec)
64
+ loop do
65
+ raise "wrong spec in fiber block" unless spec.is_a?(Hash)
66
+
67
+ begin
68
+ before!(spec)
69
+ spec[:block].call# *Fiber.current.args
70
+ after!(spec)
71
+ rescue Exception => e
72
+ # don't raise fiber exceptions
73
+ error!(e)
74
+ end
75
+
76
+ unless @queue.empty?
77
+ spec = @queue.shift
78
+ next
79
+ end
80
+
81
+ spec = checkin
82
+ end
83
+ end
84
+
85
+ # Check-in fiber to pool
86
+ def checkin
87
+ @reserved.delete ::Fiber.current.object_id
88
+ @pool.unshift ::Fiber.current
89
+ ::Fiber.yield
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,24 @@
1
+ class Fiber
2
+ class Mock
3
+ attr_reader :scope
4
+ attr_reader :result
5
+
6
+ def initialize(scope)
7
+ @scope = scope
8
+ end
9
+
10
+ def resume(result)
11
+ @result = result
12
+ @completed = true
13
+ @scope.check
14
+ end
15
+
16
+ def completed?
17
+ !!@completed
18
+ end
19
+
20
+ def leave(e, *a)
21
+ resume e.new(*a)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ module Fibre
2
+ module Rack
3
+ class FiberPool
4
+ def initialize(app, options={})
5
+ @app = app
6
+ yield Fibre.pool if block_given?
7
+ @rescue_exception = options[:rescue_exception] || (->(env, ex) { [500, {}, ["Internal Server Error"]] })
8
+ end
9
+
10
+ def call(env)
11
+ call_app = lambda do
12
+ result = @app.call(env)
13
+ env['async.callback'].call result
14
+ end
15
+
16
+ Fibre.pool.checkout(&call_app)
17
+ throw :async
18
+ rescue => ex
19
+ @rescue_exception[env, ex]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,49 @@
1
+ class Fiber
2
+ class Scope
3
+ attr_accessor :mocks
4
+ attr_accessor :fiber
5
+
6
+ class <<self
7
+
8
+ def scope
9
+ raise "nested scopes" if Fiber.current[:scope]
10
+ Fiber.current[:scope] = self.new(Fiber.current)
11
+ res = yield
12
+ Fiber.current[:scope] = nil
13
+ Fiber.yield!
14
+ res
15
+ end
16
+
17
+ def scope?
18
+ !!Fiber.current[:scope]
19
+ end
20
+
21
+ def sync
22
+ scope = Fiber.current[:scope]
23
+ mock = Fiber::Mock.new(scope)
24
+ scope.mocks << mock
25
+ yield(mock) if block_given?
26
+ mock
27
+ end
28
+ end
29
+
30
+ def initialize(fiber)
31
+ @fiber = fiber
32
+ @mocks = []
33
+ end
34
+
35
+ def check
36
+ fiber.resume if @mocks.all?(&:completed?)
37
+ end
38
+
39
+
40
+ module Iterator
41
+ def sync
42
+ res = Fiber.scope do
43
+ collect(&:sync)
44
+ end
45
+ res.collect(&:result)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ module Fibre
2
+ VERSION = "0.9.0"
3
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+ describe Fibre do
3
+ using EventObject
4
+
5
+ it "should create default pool with default size" do
6
+ expect(Fibre.pool.size).to be(20)
7
+ end
8
+
9
+ it "should have right root fiber" do
10
+ expect(Fibre.root).to equal(Fiber.current)
11
+ expect(Fiber.current.root?).to be true
12
+ end
13
+
14
+ let(:probe) { lambda {} }
15
+
16
+ it "should checkout fiber" do
17
+ expect(probe).to receive(:call)
18
+ Fibre.pool.checkout(&probe)
19
+ end
20
+
21
+ it "rescue error in fiber" do
22
+ expect(probe).to receive(:call)
23
+ Fibre.pool.on(:error, &probe)
24
+ Fibre.pool.checkout do
25
+ raise
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,9 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require File.expand_path("./lib/fibre")
5
+
6
+ RSpec.configure do |config|
7
+ config.color = true
8
+ config.mock_framework = :rspec
9
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fibre
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ platform: ruby
6
+ authors:
7
+ - che
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
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: 3.0.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: event_object
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.9'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.9'
69
+ description:
70
+ email:
71
+ - max@kupibilet.ru
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - fibre.gemspec
82
+ - lib/fibre.rb
83
+ - lib/fibre/core_ext/fiber.rb
84
+ - lib/fibre/fiber_pool.rb
85
+ - lib/fibre/mock.rb
86
+ - lib/fibre/rack/fiber_pool.rb
87
+ - lib/fibre/scope.rb
88
+ - lib/fibre/version.rb
89
+ - spec/fibre_spec.rb
90
+ - spec/spec_helper.rb
91
+ homepage: ''
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 2.1.0
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: 2.3.0
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.4.1
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: Fibre - fiber pool, mock and scoping fibres
115
+ test_files:
116
+ - spec/fibre_spec.rb
117
+ - spec/spec_helper.rb