fiber_space 0.1.1

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.
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: []