type_fusion 0.0.2 → 0.0.3
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 +4 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +30 -1
- data/README.md +67 -6
- data/lib/type_fusion/config.rb +39 -0
- data/lib/type_fusion/rack/middleware.rb +22 -0
- data/lib/type_fusion/rails/railtie.rb +11 -0
- data/lib/type_fusion/sample_call.rb +2 -0
- data/lib/type_fusion/sample_job.rb +15 -0
- data/lib/type_fusion/sampler.rb +11 -3
- data/lib/type_fusion/version.rb +1 -1
- data/lib/type_fusion.rb +27 -0
- data/test.rb +9 -1
- metadata +21 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fd6c97b4b4bb6eeecea4ff23e108c24a7564ac3d85e2231352824cd27bf160e
|
4
|
+
data.tar.gz: a438ca7330e335d8d1922c967a24ef46a23403d6825e0e7a4740aafa6e93dcf6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48d5ea9c6b6c52e8fe44bd8b1ea295f96ff5e48e737985b7c75d21b5c8379d2934b8dfe6e0fa41acfc85aa4104427a7e86354ebed07823d81e37c85a5060d7e3
|
7
|
+
data.tar.gz: 54d0eae75e1b154a249ddf5eecf6facf7694d3fc43d0ea3e3c022e7225a0510f7e2d58758fbbba885f6b45c16f35236653054e3e1d9ea199b6dfb16696b88fa3
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.0.3] - 2023-08-13
|
4
|
+
|
5
|
+
- Introduce `TypeFusion::Middleware` to allow type-sampling in Rack-powered apps
|
6
|
+
- Introduce `TypeFusion::Railtie` to automatically setup type-sampling in Rails apps
|
7
|
+
- Introduce `TypeFusion::Config` to control sampling
|
8
|
+
- Add `config.type_sample_call_rate` config
|
9
|
+
- Add `config.type_sample_request` config
|
10
|
+
- Add `config.type_sample_tracepoint_path` config
|
11
|
+
|
3
12
|
## [0.0.2] - 2023-08-12
|
4
13
|
|
5
14
|
- Initial Proof-of-Concept release
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,19 +1,42 @@
|
|
1
|
+
GIT
|
2
|
+
remote: https://github.com/marcoroth/litestack.git
|
3
|
+
revision: 1911d5ef35f474425fb4e17a11a7d40deb4008a8
|
4
|
+
specs:
|
5
|
+
litestack (0.2.6)
|
6
|
+
erubi
|
7
|
+
hanami-router
|
8
|
+
oj
|
9
|
+
rack
|
10
|
+
sqlite3
|
11
|
+
tilt
|
12
|
+
|
1
13
|
PATH
|
2
14
|
remote: .
|
3
15
|
specs:
|
4
|
-
type_fusion (0.0.
|
16
|
+
type_fusion (0.0.3)
|
17
|
+
litestack
|
5
18
|
|
6
19
|
GEM
|
7
20
|
remote: https://rubygems.org/
|
8
21
|
specs:
|
9
22
|
ast (2.4.2)
|
23
|
+
erubi (1.12.0)
|
24
|
+
hanami-router (0.6.2)
|
25
|
+
hanami-utils (~> 0.7)
|
26
|
+
http_router (~> 0.11)
|
27
|
+
hanami-utils (0.9.2)
|
28
|
+
http_router (0.11.2)
|
29
|
+
rack (>= 1.0.0)
|
30
|
+
url_mount (~> 0.2.1)
|
10
31
|
json (2.6.3)
|
11
32
|
minitest (5.19.0)
|
33
|
+
oj (3.15.1)
|
12
34
|
parallel (1.23.0)
|
13
35
|
parser (3.2.2.3)
|
14
36
|
ast (~> 2.4.1)
|
15
37
|
racc
|
16
38
|
racc (1.7.1)
|
39
|
+
rack (3.0.8)
|
17
40
|
rainbow (3.1.1)
|
18
41
|
rake (13.0.6)
|
19
42
|
regexp_parser (2.8.1)
|
@@ -31,13 +54,19 @@ GEM
|
|
31
54
|
rubocop-ast (1.29.0)
|
32
55
|
parser (>= 3.2.1.0)
|
33
56
|
ruby-progressbar (1.13.0)
|
57
|
+
sqlite3 (1.6.3-x86_64-darwin)
|
58
|
+
sqlite3 (1.6.3-x86_64-linux)
|
59
|
+
tilt (2.2.0)
|
34
60
|
unicode-display_width (2.4.2)
|
61
|
+
url_mount (0.2.1)
|
62
|
+
rack
|
35
63
|
|
36
64
|
PLATFORMS
|
37
65
|
x86_64-darwin-22
|
38
66
|
x86_64-linux
|
39
67
|
|
40
68
|
DEPENDENCIES
|
69
|
+
litestack!
|
41
70
|
minitest (~> 5.0)
|
42
71
|
rake (~> 13.0)
|
43
72
|
rubocop (~> 1.21)
|
data/README.md
CHANGED
@@ -14,16 +14,77 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
14
14
|
gem install type_fusion
|
15
15
|
```
|
16
16
|
|
17
|
-
|
17
|
+
#### Rack
|
18
18
|
|
19
19
|
```ruby
|
20
|
+
require "type_fusion/rack/middleware"
|
21
|
+
|
22
|
+
use TypeFusion::Middleware
|
23
|
+
```
|
24
|
+
|
25
|
+
#### Rails
|
26
|
+
|
27
|
+
Adding the gem to your applications Gemfile will automatically setup `type_fusion`.
|
28
|
+
|
29
|
+
|
30
|
+
## Configuration
|
31
|
+
|
32
|
+
Setup `TypeFusion` in an initializer
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
# config/initializers/type_fusion.rb
|
36
|
+
|
20
37
|
require "type_fusion"
|
38
|
+
|
39
|
+
TypeFusion.config do |config|
|
40
|
+
|
41
|
+
# === type_sample_request
|
42
|
+
#
|
43
|
+
# Set type_sample_request to a lambda which resolves to true/false
|
44
|
+
# to set if type sampling should be enabled for the whole rack request.
|
45
|
+
#
|
46
|
+
# Default: ->(rack_env) { [true, false, false, false].sample }
|
47
|
+
#
|
48
|
+
# config.type_sample_request = ->(rack_env) { [true, false, false, false].sample }
|
49
|
+
|
50
|
+
|
51
|
+
# === type_sample_tracepoint_path
|
52
|
+
#
|
53
|
+
# Set type_sample_tracepoint_path to a lambda which resolves
|
54
|
+
# to true/false to check if a tracepoint_path should be sampled
|
55
|
+
# or not.
|
56
|
+
#
|
57
|
+
# This can be useful when you only want to sample method calls for
|
58
|
+
# certain gems or want to exclude a gem from being sampled.
|
59
|
+
#
|
60
|
+
# Example:
|
61
|
+
# config.type_sample_tracepoint_path = ->(tracepoint_path) {
|
62
|
+
# # only sample calls for the Nokogiri gem
|
63
|
+
# tracepoint_path.include?("nokogiri")
|
64
|
+
# }
|
65
|
+
#
|
66
|
+
# Default: ->(tracepoint_path) { true }
|
67
|
+
#
|
68
|
+
# config.type_sample_tracepoint_path = ->(tracepoint_path) { true }
|
69
|
+
|
70
|
+
|
71
|
+
# === type_sample_call_rate
|
72
|
+
#
|
73
|
+
# Set type_sample_call_rate to 1.0 to capture 100% of method calls
|
74
|
+
# within a rack request.
|
75
|
+
#
|
76
|
+
# Default: 0.001
|
77
|
+
#
|
78
|
+
# config.type_sample_call_rate = 0.001
|
79
|
+
end
|
21
80
|
```
|
22
81
|
|
82
|
+
## Usage
|
83
|
+
|
23
84
|
#### Type sample inside a block
|
24
85
|
|
25
86
|
```ruby
|
26
|
-
TypeFusion
|
87
|
+
TypeFusion.with_sampling do
|
27
88
|
# run code you want to type sample here
|
28
89
|
end
|
29
90
|
```
|
@@ -31,22 +92,22 @@ end
|
|
31
92
|
#### Type sample globally
|
32
93
|
|
33
94
|
```ruby
|
34
|
-
TypeFusion
|
95
|
+
TypeFusion.start
|
35
96
|
|
36
97
|
# run code you want to type sample here
|
37
98
|
|
38
|
-
TypeFusion
|
99
|
+
TypeFusion.stop
|
39
100
|
```
|
40
101
|
|
41
102
|
#### Retrieve the samples
|
42
103
|
|
43
104
|
```ruby
|
44
|
-
TypeFusion::Sampler.instance.
|
105
|
+
TypeFusion::Sampler.instance.samples
|
45
106
|
# => [...]
|
46
107
|
```
|
47
108
|
|
48
109
|
```ruby
|
49
|
-
TypeFusion::Sampler.instance.
|
110
|
+
TypeFusion::Sampler.instance.samples.first
|
50
111
|
|
51
112
|
# => #<struct TypeFusion::SampleCall
|
52
113
|
# gem_and_version="nokogiri-1.15.4-x86_64-darwin",
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "singleton"
|
4
|
+
|
5
|
+
module TypeFusion
|
6
|
+
class << self
|
7
|
+
def config
|
8
|
+
@config ||= Config.instance
|
9
|
+
|
10
|
+
yield @config if block_given?
|
11
|
+
|
12
|
+
@config
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Config
|
17
|
+
include Singleton
|
18
|
+
|
19
|
+
attr_accessor :type_sample_call_rate, :type_sample_request, :type_sample_tracepoint_path
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@type_sample_call_rate = 0.001
|
23
|
+
@type_sample_request = ->(_env) { [true, false, false, false].sample }
|
24
|
+
@type_sample_tracepoint_path = ->(_tracepoint_path) { true }
|
25
|
+
end
|
26
|
+
|
27
|
+
def type_sample_request?(env)
|
28
|
+
type_sample_request&.call(env)
|
29
|
+
end
|
30
|
+
|
31
|
+
def type_sample_tracepoint_path?(env)
|
32
|
+
type_sample_tracepoint_path&.call(env)
|
33
|
+
end
|
34
|
+
|
35
|
+
def type_sample_call?
|
36
|
+
type_sample_call_rate > rand
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "type_fusion/sampler"
|
4
|
+
|
5
|
+
module TypeFusion
|
6
|
+
class Middleware
|
7
|
+
def initialize(app)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
if TypeFusion.config.type_sample_request?(env)
|
13
|
+
puts "[TypeFusion] Type-sampling this request"
|
14
|
+
TypeFusion.start
|
15
|
+
end
|
16
|
+
|
17
|
+
@app.call(env)
|
18
|
+
ensure
|
19
|
+
TypeFusion.stop
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/type_fusion/sampler.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "singleton"
|
4
|
-
require "json"
|
5
4
|
|
6
5
|
module TypeFusion
|
7
6
|
class Sampler
|
@@ -23,7 +22,7 @@ module TypeFusion
|
|
23
22
|
|
24
23
|
def trace
|
25
24
|
@trace ||= TracePoint.trace(:call) do |tracepoint|
|
26
|
-
if tracepoint.path
|
25
|
+
if sample?(tracepoint.path)
|
27
26
|
receiver = begin
|
28
27
|
tracepoint.binding.receiver.name
|
29
28
|
rescue StandardError
|
@@ -36,13 +35,16 @@ module TypeFusion
|
|
36
35
|
args = tracepoint.parameters.map(&:reverse).to_h
|
37
36
|
parameters = extract_parameters(args, tracepoint.binding)
|
38
37
|
|
39
|
-
|
38
|
+
sample = SampleCall.new(
|
40
39
|
gem_and_version: gem_and_version,
|
41
40
|
receiver: receiver,
|
42
41
|
method_name: method_name,
|
43
42
|
location: location,
|
44
43
|
parameters: parameters,
|
45
44
|
)
|
45
|
+
|
46
|
+
samples << sample
|
47
|
+
SampleJob.perform_async(sample)
|
46
48
|
end
|
47
49
|
end.tap(&:disable)
|
48
50
|
end
|
@@ -62,6 +64,12 @@ module TypeFusion
|
|
62
64
|
|
63
65
|
private
|
64
66
|
|
67
|
+
def sample?(tracepoint_path)
|
68
|
+
TypeFusion.config.type_sample_call? &&
|
69
|
+
TypeFusion.config.type_sample_tracepoint_path?(tracepoint_path) &&
|
70
|
+
tracepoint_path.start_with?(gem_path)
|
71
|
+
end
|
72
|
+
|
65
73
|
def type_for_object(object)
|
66
74
|
case object
|
67
75
|
when Hash
|
data/lib/type_fusion/version.rb
CHANGED
data/lib/type_fusion.rb
CHANGED
@@ -1,8 +1,35 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "type_fusion/version"
|
4
|
+
require_relative "type_fusion/config"
|
4
5
|
require_relative "type_fusion/sample_call"
|
6
|
+
require_relative "type_fusion/sample_job"
|
5
7
|
require_relative "type_fusion/sampler"
|
6
8
|
|
7
9
|
module TypeFusion
|
10
|
+
class << self
|
11
|
+
def start
|
12
|
+
return if Sampler.instance.trace.enabled?
|
13
|
+
|
14
|
+
puts "[TypeFusion] Starting Sampler..."
|
15
|
+
Sampler.instance.trace.enable
|
16
|
+
end
|
17
|
+
|
18
|
+
def stop
|
19
|
+
return unless Sampler.instance.trace.enabled?
|
20
|
+
|
21
|
+
puts "[TypeFusion] Stopping Sampler..."
|
22
|
+
Sampler.instance.trace.disable
|
23
|
+
end
|
24
|
+
|
25
|
+
def with_sampling
|
26
|
+
start
|
27
|
+
|
28
|
+
yield if block_given?
|
29
|
+
|
30
|
+
stop
|
31
|
+
end
|
32
|
+
end
|
8
33
|
end
|
34
|
+
|
35
|
+
require_relative "type_fusion/rails/railtie" if defined?(Rails::Railtie)
|
data/test.rb
CHANGED
@@ -3,7 +3,15 @@
|
|
3
3
|
require "nokogiri"
|
4
4
|
require_relative "lib/type_fusion"
|
5
5
|
|
6
|
-
TypeFusion
|
6
|
+
TypeFusion.config do |config|
|
7
|
+
config.type_sample_call_rate = 1.0
|
8
|
+
|
9
|
+
config.type_sample_tracepoint_path = lambda do |tracepoint_path|
|
10
|
+
tracepoint_path.include?("nokogiri")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
TypeFusion.with_sampling do
|
7
15
|
Nokogiri.parse("<h1></h1>")
|
8
16
|
end
|
9
17
|
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: type_fusion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marco Roth
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-08-
|
12
|
-
dependencies:
|
11
|
+
date: 2023-08-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: litestack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
description: Community-contributed sample data for Ruby types
|
14
28
|
email:
|
15
29
|
- marco.roth@intergga.ch
|
@@ -26,7 +40,11 @@ files:
|
|
26
40
|
- README.md
|
27
41
|
- Rakefile
|
28
42
|
- lib/type_fusion.rb
|
43
|
+
- lib/type_fusion/config.rb
|
44
|
+
- lib/type_fusion/rack/middleware.rb
|
45
|
+
- lib/type_fusion/rails/railtie.rb
|
29
46
|
- lib/type_fusion/sample_call.rb
|
47
|
+
- lib/type_fusion/sample_job.rb
|
30
48
|
- lib/type_fusion/sampler.rb
|
31
49
|
- lib/type_fusion/version.rb
|
32
50
|
- sig/type_fusion.rbs
|