fibre 0.9.0

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,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