diverter 0.0.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 +7 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +23 -0
- data/README.md +44 -0
- data/Rakefile +5 -0
- data/diverter.gemspec +24 -0
- data/lib/diverter/version.rb +3 -0
- data/lib/diverter.rb +21 -0
- data/spec/diverter_spec.rb +57 -0
- data/spec/spec_helper.rb +2 -0
- metadata +100 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2b1f6a4d524f4b2f602291f5b6ffa9907cb6ea9bd1d6df9f1029b83d0029002c
|
4
|
+
data.tar.gz: 976cb8b2bd3d951c82588a3756933d4c9e1d5cdc3034188244891d053defc1f2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ffe5489de472fe31f1a582fe9dd6827f3e6941676ee88754c2743f4d0b27fc78a04e999df36aae1650a5042f4be5ce5356192e39d3db7e547ad519f9a0f6b7f4
|
7
|
+
data.tar.gz: 4f612a8ab935cad717d62e15ce8a94e85dfcd18fc0c98c2067d3dc8ce94e461a3f2c18e4c92b0bb042433eb9b0593c5f5acfa3714cbcb29b90b061094ac1a2d8
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2024 Robin Stammer
|
2
|
+
|
3
|
+
|
4
|
+
MIT License
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# diverter
|
2
|
+
|
3
|
+
Lightweight Ruby library for executing tasks in a seperate Ruby subprocesses
|
4
|
+
|
5
|
+
### Motivation
|
6
|
+
|
7
|
+
Ruby very rarely releases memory back to the operating system once allocated.
|
8
|
+
This gem realizes a neat trick as suggested by the Book "Ruby Performance Optimization"
|
9
|
+
by [Alexander Dymo](https://github.com/adymo): https://pragprog.com/book/adrpo/ruby-performance-optimization
|
10
|
+
|
11
|
+
The crucial point is that exiting a subprocess will force Ruby to release
|
12
|
+
all the memory allocated in the subprocess back to the OS.
|
13
|
+
|
14
|
+
### Synopsis
|
15
|
+
|
16
|
+
```Ruby
|
17
|
+
class DecadentMemoryConsumer
|
18
|
+
…
|
19
|
+
|
20
|
+
# Needs a lot of memory
|
21
|
+
# to execute some magical
|
22
|
+
# task
|
23
|
+
|
24
|
+
…
|
25
|
+
end
|
26
|
+
|
27
|
+
# If the predicate :memory_almost_exceeded? evaluates to true,
|
28
|
+
# the block will be executed in a forked subprocess
|
29
|
+
# that is forced to terminate afterwards
|
30
|
+
Diverter.new(condition: memory_almost_exceeded?) do
|
31
|
+
DecadentMemoryConsumer.perform_memory_expensive_operation
|
32
|
+
end
|
33
|
+
|
34
|
+
# condition defaults to true, so this is equivalent of condition set to true
|
35
|
+
Diverter.new do
|
36
|
+
DecadentMemoryConsumer.perform_memory_expensive_operation
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
### Changelog
|
41
|
+
|
42
|
+
#### 0.0.1
|
43
|
+
|
44
|
+
Initial version
|
data/Rakefile
ADDED
data/diverter.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'diverter/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "diverter"
|
8
|
+
spec.version = Diverter::VERSION
|
9
|
+
spec.authors = ["Robin Stammer\n"]
|
10
|
+
spec.email = ["robin.stammer@posteo.de"]
|
11
|
+
spec.summary = %q{Lightweight tool for execution of Ruby code in a forked Ruby process}
|
12
|
+
spec.description = %q{Lightweight tool for execution of Ruby code in a forked Ruby process}
|
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.add_development_dependency "bundler"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
end
|
data/lib/diverter.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "diverter/version"
|
2
|
+
|
3
|
+
class Diverter
|
4
|
+
|
5
|
+
def initialize(condition: true)
|
6
|
+
return unless block_given?
|
7
|
+
|
8
|
+
if !!condition
|
9
|
+
pid = fork do
|
10
|
+
yield
|
11
|
+
exit!(0)
|
12
|
+
end
|
13
|
+
|
14
|
+
# ensure the child process has terminated
|
15
|
+
Process::waitpid(pid)
|
16
|
+
else
|
17
|
+
yield
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Diverter do
|
4
|
+
|
5
|
+
class Monkey
|
6
|
+
class << self
|
7
|
+
def cheek
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'has a version number' do
|
13
|
+
expect(Diverter::VERSION).not_to be nil
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'its constructor' do
|
17
|
+
context 'without condition delivered' do
|
18
|
+
subject { described_class.new { Monkey.cheek } }
|
19
|
+
|
20
|
+
it 'executes block in a forked process' do
|
21
|
+
expect_any_instance_of(Object).to receive(:fork).and_call_original
|
22
|
+
subject
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with condition false' do
|
27
|
+
subject { described_class.new(condition: false) { Monkey.cheek } }
|
28
|
+
|
29
|
+
it 'executes block in unforked' do
|
30
|
+
expect(Monkey).to receive(:cheek)
|
31
|
+
expect_any_instance_of(Object).not_to receive(:fork)
|
32
|
+
subject
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'with condition nil' do
|
37
|
+
subject { described_class.new(condition: nil) { Monkey.cheek } }
|
38
|
+
|
39
|
+
it 'executes block in unforked' do
|
40
|
+
expect(Monkey).to receive(:cheek)
|
41
|
+
expect_any_instance_of(Object).not_to receive(:fork)
|
42
|
+
subject
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
context 'with condition true' do
|
48
|
+
subject { described_class.new(condition: true) { Monkey.cheek } }
|
49
|
+
|
50
|
+
it 'executes block in a forked process' do
|
51
|
+
expect_any_instance_of(Object).to receive(:fork).and_call_original
|
52
|
+
subject
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: diverter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- 'Robin Stammer
|
8
|
+
|
9
|
+
'
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2024-09-20 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: bundler
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ">="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '0'
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: rake
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
type: :development
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: rspec
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
type: :development
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
description: Lightweight tool for execution of Ruby code in a forked Ruby process
|
58
|
+
email:
|
59
|
+
- robin.stammer@posteo.de
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- ".gitignore"
|
65
|
+
- ".rspec"
|
66
|
+
- Gemfile
|
67
|
+
- LICENSE.txt
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- diverter.gemspec
|
71
|
+
- lib/diverter.rb
|
72
|
+
- lib/diverter/version.rb
|
73
|
+
- spec/diverter_spec.rb
|
74
|
+
- spec/spec_helper.rb
|
75
|
+
homepage: ''
|
76
|
+
licenses:
|
77
|
+
- MIT
|
78
|
+
metadata: {}
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubygems_version: 3.5.17
|
95
|
+
signing_key:
|
96
|
+
specification_version: 4
|
97
|
+
summary: Lightweight tool for execution of Ruby code in a forked Ruby process
|
98
|
+
test_files:
|
99
|
+
- spec/diverter_spec.rb
|
100
|
+
- spec/spec_helper.rb
|