fiber_space 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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: []