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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce0738a57fd5c0b08679b9ea5fd5fe16ddd786326a8269aa09905acb9b7bb7ac
4
- data.tar.gz: c55387825018723f436f302d8ec6f842a9e9a635ca0c779a9a498d32a906ed91
3
+ metadata.gz: 7fd6c97b4b4bb6eeecea4ff23e108c24a7564ac3d85e2231352824cd27bf160e
4
+ data.tar.gz: a438ca7330e335d8d1922c967a24ef46a23403d6825e0e7a4740aafa6e93dcf6
5
5
  SHA512:
6
- metadata.gz: 9ba2541d870cd306acf5a5c8a06367117aff283a28502940424d2931641f9405c85a053684ff73e74a163cce14d15409706f00cf69de7d0c22f8caaf30586cd4
7
- data.tar.gz: 4b929bacae1bc294fbdde9df386aa4833329252f46a438c8daae53049fb9687fca7296fa0ca3f4e4db9b576bc00241d249c62cf5b500e04561a9dc1ebb50590e
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
@@ -7,3 +7,5 @@ gemspec
7
7
  gem "minitest", "~> 5.0"
8
8
  gem "rake", "~> 13.0"
9
9
  gem "rubocop", "~> 1.21"
10
+
11
+ gem "litestack", github: "marcoroth/litestack"
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.1)
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
- ## Usage
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::Sampler.instance.with_sampling do
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::Sampler.instance.trace.enable
95
+ TypeFusion.start
35
96
 
36
97
  # run code you want to type sample here
37
98
 
38
- TypeFusion::Sampler.instance.trace.disable
99
+ TypeFusion.stop
39
100
  ```
40
101
 
41
102
  #### Retrieve the samples
42
103
 
43
104
  ```ruby
44
- TypeFusion::Sampler.instance.trace.samples
105
+ TypeFusion::Sampler.instance.samples
45
106
  # => [...]
46
107
  ```
47
108
 
48
109
  ```ruby
49
- TypeFusion::Sampler.instance.trace.samples.first
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
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TypeFusion
4
+ class Railtie < ::Rails::Railtie
5
+ initializer "type_fusion.middleware" do |app|
6
+ require "type_fusion/rack/middleware"
7
+
8
+ app.config.middleware.use TypeFusion::Middleware
9
+ end
10
+ end
11
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "json"
4
+
3
5
  module TypeFusion
4
6
  SampleCall = Struct.new(:gem_and_version, :receiver, :method_name, :location, :parameters) do
5
7
  def to_s
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "litestack"
4
+
5
+ module TypeFusion
6
+ class SampleJob
7
+ include Litejob
8
+
9
+ self.queue = :default
10
+
11
+ def perform(sample)
12
+ puts sample.inspect
13
+ end
14
+ end
15
+ end
@@ -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.start_with?(gem_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
- samples << SampleCall.new(
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TypeFusion
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.3"
5
5
  end
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::Sampler.instance.with_sampling do
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.2
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 00:00:00.000000000 Z
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