fiber_space 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/fiber_space/chain.rb +107 -0
- data/lib/fiber_space/container.rb +98 -0
- data/lib/fiber_space/wrapper.rb +77 -0
- data/lib/fiber_space.rb +47 -0
- metadata +67 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: abe3d0bb4dc3359f6888ed84d53c579e0bf4d1e8049e5ec140a29adb664b3b9a
|
4
|
+
data.tar.gz: f5cf577cbc73510e640991e333de0d51c81a2019997a655188b4055d4f7c1bfc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f0f463ae5c6319fdfbfd7964ed2d93573d8de4e6d6b1a625ab59faea7badb9db831c87918518e1221ca94ede9fb07f4e259bcdcb42c45924a920ca544c002133
|
7
|
+
data.tar.gz: 148606be51d318644a6e1c18d8121e7a9b85805cea2892b5d9ca08b1a9cdfb1ab19cbcf6048111dd6e020969d9fefc21988b30f792c9fa1de5cd1aa5d007fe2c
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module FiberSpace
|
2
|
+
# A FiberChain encapsulates and organizes a SortedSet of Fiber or FiberContainer objects. It facilitates the sequential execution of Fiber and FiberContainer objects.
|
3
|
+
class FiberChain
|
4
|
+
|
5
|
+
# Constructs a new FiberChain
|
6
|
+
# @param containers [Array] collection of Fibers or FiberContainers.
|
7
|
+
def initialize(*containers)
|
8
|
+
@stack = SortedSet.new
|
9
|
+
containers.each { |fiber_container| register(fiber_container) }
|
10
|
+
end
|
11
|
+
|
12
|
+
# Performs a single iteration of execution on the FiberChain#stack.
|
13
|
+
def iterate
|
14
|
+
@worker ||= Fiber.new do
|
15
|
+
loop do
|
16
|
+
if @stack.any?(&:completed?)
|
17
|
+
@stack.delete_if(&:completed?)
|
18
|
+
prepare
|
19
|
+
end
|
20
|
+
rescue StandardError => e
|
21
|
+
puts 'An error occurred during FiberChain#iterate!'
|
22
|
+
puts e.message
|
23
|
+
puts e.backtrace&.join("\n")
|
24
|
+
ensure
|
25
|
+
break if complete?
|
26
|
+
|
27
|
+
Fiber.yield(@stack.first.resume)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
@worker.resume
|
31
|
+
end
|
32
|
+
|
33
|
+
# Begins executing all items within the FiberChain#stack until all items are complete or the stack is empty.
|
34
|
+
def execute
|
35
|
+
iterate until complete?
|
36
|
+
end
|
37
|
+
|
38
|
+
# Pushes an item to the FiberChain#stack
|
39
|
+
# @param item [Fiber, FiberContainer] the item
|
40
|
+
def register(item)
|
41
|
+
@stack << case item
|
42
|
+
when Fiber then FiberContainer.new(source: item)
|
43
|
+
when FiberContainer then item
|
44
|
+
else raise TypeError, 'Expecting Fiber or FiberContainer!'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# The length of the FiberChain#stack
|
49
|
+
# @return [Integer] the length
|
50
|
+
def length
|
51
|
+
@stack.length
|
52
|
+
end
|
53
|
+
|
54
|
+
# Has all elements of the FiberChain#stack completed execution?
|
55
|
+
# @return [Boolean]
|
56
|
+
def complete?
|
57
|
+
@stack.empty? || @stack.all?(&:completed?)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Links all elements of the FiberChain#stack to their subsequent neighbor elements via FiberContainer#target.
|
63
|
+
def prepare
|
64
|
+
current = @stack.to_a
|
65
|
+
current.each do |item|
|
66
|
+
next if item.is_a?(Fiber)
|
67
|
+
|
68
|
+
if item == current.last
|
69
|
+
# Complete the loop
|
70
|
+
item.target = current.first
|
71
|
+
else
|
72
|
+
item.chain = true
|
73
|
+
item.target = current[current.index(item) + 1]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
@stack = SortedSet.new(current)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Copyright (c) 2022, Patrick W.
|
82
|
+
# All rights reserved.
|
83
|
+
#
|
84
|
+
# Redistribution and use in source and binary forms, with or without
|
85
|
+
# modification, are permitted provided that the following conditions are met:
|
86
|
+
#
|
87
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
88
|
+
# list of conditions and the following disclaimer.
|
89
|
+
#
|
90
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
91
|
+
# this list of conditions and the following disclaimer in the documentation
|
92
|
+
# and/or other materials provided with the distribution.
|
93
|
+
#
|
94
|
+
# * Neither the name of the copyright holder nor the names of its
|
95
|
+
# contributors may be used to endorse or promote products derived from
|
96
|
+
# this software without specific prior written permission.
|
97
|
+
#
|
98
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
99
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
100
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
101
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
102
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
103
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
104
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
105
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
106
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
107
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module FiberSpace
|
2
|
+
# A FiberContainer wraps a source Fiber with attributes for maintaining a specific state. It allows storing and transferring/resuming of a target who is called once the source fiber has completed it's work.
|
3
|
+
class FiberContainer
|
4
|
+
# @!attribute [r] id
|
5
|
+
# @return [Integer, String, Symbol] the ID
|
6
|
+
attr :id
|
7
|
+
|
8
|
+
# @!attribute [r] priority
|
9
|
+
# @return [Symbol] the priority
|
10
|
+
attr :priority
|
11
|
+
|
12
|
+
# @!attribute [rw] chain
|
13
|
+
# @return [Boolean] the chain flag
|
14
|
+
attr_accessor :chain
|
15
|
+
|
16
|
+
# @!attribute [rw] target
|
17
|
+
# @return [Fiber, FiberContainer] the target
|
18
|
+
attr_accessor :target
|
19
|
+
|
20
|
+
# Constructs a new FiberContainer
|
21
|
+
# @param opt [Hash] options for the Container.
|
22
|
+
# * cache [Array] cached arguments
|
23
|
+
# * id [Integer, Symbol] id of the Fiber.
|
24
|
+
# * count [Integer, Symbol] execution count.
|
25
|
+
# * target [Fiber, NilClass] target Fiber.
|
26
|
+
# * priority [Symbol] priority of the Fiber
|
27
|
+
# @return [FiberContainer]
|
28
|
+
def initialize(opt = {}, &work)
|
29
|
+
@id = opt[:id] || Druuid.gen
|
30
|
+
@count = opt[:count] || 1
|
31
|
+
@target = opt[:target] || nil
|
32
|
+
@priority = opt[:priority] || :LOW
|
33
|
+
@cache = opt[:cache] || []
|
34
|
+
@source = opt[:source] || Fiber.new do |cached|
|
35
|
+
loop do
|
36
|
+
if @count.zero? || @count.negative?
|
37
|
+
case @target
|
38
|
+
when FiberContainer then @target.completed? ? break : @target.resume
|
39
|
+
when Fiber then @target.resume if @target.alive?
|
40
|
+
else break
|
41
|
+
end
|
42
|
+
elsif @count == :once || completed?
|
43
|
+
break
|
44
|
+
else
|
45
|
+
unless completed?
|
46
|
+
@count -= 1
|
47
|
+
Fiber.yield(yield(cached))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def resume
|
55
|
+
@source.resume(@cache) unless completed?
|
56
|
+
end
|
57
|
+
|
58
|
+
# Is the fiber completed?
|
59
|
+
# @return [Boolean]
|
60
|
+
def completed?
|
61
|
+
@count.zero? || @count.negative? || !@source.alive?
|
62
|
+
end
|
63
|
+
|
64
|
+
# Mutual comparison operator
|
65
|
+
# @param other [FiberContainer] the other Fiber.
|
66
|
+
def <=>(other)
|
67
|
+
FiberSpace::FIBER_PRIORITIES[@priority] <=> FiberSpace::FIBER_PRIORITIES[other.priority]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Copyright (c) 2022, Patrick W.
|
73
|
+
# All rights reserved.
|
74
|
+
#
|
75
|
+
# Redistribution and use in source and binary forms, with or without
|
76
|
+
# modification, are permitted provided that the following conditions are met:
|
77
|
+
#
|
78
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
79
|
+
# list of conditions and the following disclaimer.
|
80
|
+
#
|
81
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
82
|
+
# this list of conditions and the following disclaimer in the documentation
|
83
|
+
# and/or other materials provided with the distribution.
|
84
|
+
#
|
85
|
+
# * Neither the name of the copyright holder nor the names of its
|
86
|
+
# contributors may be used to endorse or promote products derived from
|
87
|
+
# this software without specific prior written permission.
|
88
|
+
#
|
89
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
90
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
91
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
92
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
93
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
94
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
95
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
96
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
97
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
98
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module FiberSpace
|
2
|
+
|
3
|
+
# A Container for fiber processes.
|
4
|
+
class ProcessWrapper
|
5
|
+
|
6
|
+
attr :properties
|
7
|
+
|
8
|
+
attr :stack
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@properties = {
|
12
|
+
max_fibers: options[:max_fibers] || 0xff
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
setup_root_trapping
|
16
|
+
setup_process
|
17
|
+
end
|
18
|
+
|
19
|
+
def shutdown
|
20
|
+
@worker_thread.kill
|
21
|
+
sleep(1) while @worker_thread.alive?
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def setup_root_trapping
|
27
|
+
Signal.trap('INT') do
|
28
|
+
puts 'Caught INT signal!'
|
29
|
+
Process.kill('INT', @worker_process)
|
30
|
+
Process.wait(@worker_process)
|
31
|
+
rescue StandardError => e
|
32
|
+
puts 'An error occurred during shutdown!'
|
33
|
+
puts e.backtrace&.join("\n")
|
34
|
+
end
|
35
|
+
|
36
|
+
Signal.trap('TERM') do
|
37
|
+
puts 'Caught TERM signal.'
|
38
|
+
begin
|
39
|
+
Process.kill('TERM', @worker_process)
|
40
|
+
Process.wait(@worker_process)
|
41
|
+
rescue StandardError => e
|
42
|
+
puts 'An error occurred during shutdown!'
|
43
|
+
puts e.backtrace&.join("\n")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def setup_child_trapping
|
49
|
+
Signal.trap('INT') do
|
50
|
+
puts 'Child caught INT!!'
|
51
|
+
ensure
|
52
|
+
shutdown
|
53
|
+
end
|
54
|
+
|
55
|
+
Signal.trap('TERM') do
|
56
|
+
puts 'Child caught TERM!!'
|
57
|
+
ensure
|
58
|
+
shutdown
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def setup_process
|
63
|
+
@worker_process = Process.spawn do
|
64
|
+
setup_child_trapping
|
65
|
+
setup_worker
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def setup_worker
|
70
|
+
@worker_thread = Thread.new do
|
71
|
+
loop do
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/fiber_space.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Dir[File.dirname(__FILE__)].each { |file| $LOAD_PATH.unshift(file) if File.directory? file }
|
4
|
+
|
5
|
+
require 'druuid'
|
6
|
+
require 'fiber'
|
7
|
+
require 'set'
|
8
|
+
|
9
|
+
# A set of tools to organize and work with Fibers.
|
10
|
+
module FiberSpace
|
11
|
+
|
12
|
+
# @!attribute [r] FIBER_PRIORITIES
|
13
|
+
# @return [Hash] priorities for Fibers.
|
14
|
+
FIBER_PRIORITIES = { HIGH: 1, MED: 2, LOW: 3 }.freeze
|
15
|
+
|
16
|
+
autoload :FiberContainer, 'fiber_space/container'
|
17
|
+
autoload :FiberChain, 'fiber_space/chain'
|
18
|
+
autoload :ProcessWrapper, 'fiber_space/wrapper'
|
19
|
+
end
|
20
|
+
|
21
|
+
# Copyright (c) 2022, Patrick W.
|
22
|
+
# All rights reserved.
|
23
|
+
#
|
24
|
+
# Redistribution and use in source and binary forms, with or without
|
25
|
+
# modification, are permitted provided that the following conditions are met:
|
26
|
+
#
|
27
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
28
|
+
# list of conditions and the following disclaimer.
|
29
|
+
#
|
30
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
31
|
+
# this list of conditions and the following disclaimer in the documentation
|
32
|
+
# and/or other materials provided with the distribution.
|
33
|
+
#
|
34
|
+
# * Neither the name of the copyright holder nor the names of its
|
35
|
+
# contributors may be used to endorse or promote products derived from
|
36
|
+
# this software without specific prior written permission.
|
37
|
+
#
|
38
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
39
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
40
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
41
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
42
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
43
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
44
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
45
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
46
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
47
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fiber_space
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Patrick W.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-03-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: druuid
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.0.2
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.0.2
|
33
|
+
description:
|
34
|
+
email: Sickday@pm.me
|
35
|
+
executables: []
|
36
|
+
extensions: []
|
37
|
+
extra_rdoc_files: []
|
38
|
+
files:
|
39
|
+
- lib/fiber_space.rb
|
40
|
+
- lib/fiber_space/chain.rb
|
41
|
+
- lib/fiber_space/container.rb
|
42
|
+
- lib/fiber_space/wrapper.rb
|
43
|
+
homepage: https://git.repos.pw/Sickday/fiber_space
|
44
|
+
licenses:
|
45
|
+
- BSD-3-Clause
|
46
|
+
metadata:
|
47
|
+
source_code_uri: https://git.repos.pw/Sickday/fiber_space
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements: []
|
63
|
+
rubygems_version: 3.1.6
|
64
|
+
signing_key:
|
65
|
+
specification_version: 4
|
66
|
+
summary: A set of tools that expand on Fiber functionality.
|
67
|
+
test_files: []
|