fiber-profiler 0.5.0 → 0.6.0

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: 1d62567e3ffd2eb3e9fd7ff6ad432d1fdda2d5d23f73284fdc91b4407851bd98
4
- data.tar.gz: d37839a3d1c08c12b4a0dadd808c46698678a7b8f646ead271a5defd5ffe4427
3
+ metadata.gz: 4eb8511c2bd355496fcb3461944f5fc7881795e7e44d13f4a59497689feaa838
4
+ data.tar.gz: 5146ceedbb0f9fc2230b5c3f50b1c0fac9ef2b424078ced732051b6e7e303431
5
5
  SHA512:
6
- metadata.gz: e7a5b9dcbfd5c80c735dd36c2961e16c2cc97bc4f1a1496f612b36552fb03a7993c0da17d0fe81d2519d0760607c51a9c36573c4ceaa249cb4d201fa1154b92d
7
- data.tar.gz: f1ff0b98c24d6c15736c3d15da1375f73f3c2fc6608d2669c554d6ae773ec8df7e21921599f314750bb99da8aeaa518f9607bc5982e8b81ce429b3acf308dd1a
6
+ metadata.gz: 427ddb031dc285d0c45c7c1dc72e0793c200b216ca3854272d675ad2cf677c58bf5a7a07bdaf043890f583527fe32ec263b0e12cf53ac11e95a90921e6576013
7
+ data.tar.gz: 625fe37c351399c0c1a5588f2577238899b2cad5b3b876d2e4fbe7c76ffdd26865c31111d68c09e04160a369cb0ca149e9c2eb97e1417dacdb7247a5a6b06861
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2025, by Samuel Williams.
5
+
6
+ # @parameter input [Input] The input to process.
7
+ def analyze(input:)
8
+ summary = {}
9
+
10
+ input.each do |sample|
11
+ duration = sample["duration"]
12
+ calls = sample["calls"]
13
+
14
+ if duration and calls
15
+ calls.each do |call|
16
+ location = "#{call["path"]}:#{call["line"]}"
17
+
18
+ summary[location] ||= {duration: 0, calls: 0, class: call["class"], method: call["method"]}
19
+ summary[location][:duration] += call["duration"]
20
+ summary[location][:calls] += 1
21
+ end
22
+ end
23
+ end
24
+
25
+ summary.sort_by{|location, data| -data[:duration]}
26
+ end
@@ -0,0 +1,72 @@
1
+ # Getting Started
2
+
3
+ This guide explains how to detect stalls using the fiber profiler.
4
+
5
+ ## Installation
6
+
7
+ Add the gem to your project:
8
+
9
+ ```bash
10
+ $ bundle add fiber-profiler
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ Instrument your code using the default profiler:
16
+
17
+ ```ruby
18
+ #!/usr/bin/env ruby
19
+
20
+ require "fiber/profiler"
21
+
22
+ profiler = Fiber::Profiler.default
23
+
24
+ profiler&.start
25
+
26
+ # Your application code:
27
+ Fiber.new do
28
+ sleep 0.1
29
+ end.resume
30
+
31
+ profiler&.stop
32
+ ```
33
+
34
+ Running this program will output the following:
35
+
36
+ ```bash
37
+ $ FIBER_PROFILER_CAPTURE=true bundle exec ./test.rb
38
+ Fiber stalled for 0.105 seconds
39
+ /Users/samuel/Developer/socketry/fiber-profiler/test.rb:11 in c-call 'Kernel#sleep' (0.105s)
40
+ ```
41
+
42
+ ## Integration with Async
43
+
44
+ The fiber profiler is optionally supported by `Async`. Simply enable the profiler using `FIBER_PROFILER_CAPTURE=true` to capture and report stalls.
45
+
46
+ ## Default Environment Variables
47
+
48
+ ### `FIBER_PROFILER_CAPTURE`
49
+
50
+ Set to `true` to enable capturing of stalled fibers.
51
+
52
+ ### `FIBER_PROFILER_CAPTURE_STALL_THRESHOLD`
53
+
54
+ Set the threshold in seconds for reporting a stalled fiber. Default is `0.01`.
55
+
56
+ ### `FIBER_PROFILER_CAPTURE_TRACK_CALLS`
57
+
58
+ Set to `true` to track calls within the fiber. Default is `true`. This can be disabled to reduce overhead.
59
+
60
+ ### `FIBER_PROFILER_CAPTURE_SAMPLE_RATE`
61
+
62
+ Set the sample rate of the profiler as a percentage of all context switches. The default is 1.0 (100%).
63
+
64
+ ## Analyzing Logs
65
+
66
+ If you collect your logs in a file (e.g. as `ndjson`) you can analyze them using the included `bake` commands:
67
+
68
+ ```bash
69
+ $ bundle exec bake input --file samples.ndjson fiber:profiler:analyze output
70
+ ```
71
+
72
+ This will aggregate all the call logs and generate a short summary, ordered by duration.
@@ -0,0 +1,11 @@
1
+ # Automatically generated context index for Utopia::Project guides.
2
+ # Do not edit then files in this directory directly, instead edit the guides and then run `bake utopia:project:agent:context:update`.
3
+ ---
4
+ description: A fiber stall profiler.
5
+ metadata:
6
+ documentation_uri: https://socketry.github.io/fiber-profiler/
7
+ source_code_uri: https://github.com/socketry/fiber-profiler.git
8
+ files:
9
+ - path: getting-started.md
10
+ title: Getting Started
11
+ description: This guide explains how to detect stalls using the fiber profiler.
@@ -181,8 +181,6 @@ static void Fiber_Profiler_Capture_compact(void *ptr) {
181
181
  static void Fiber_Profiler_Capture_free(void *ptr) {
182
182
  struct Fiber_Profiler_Capture *capture = (struct Fiber_Profiler_Capture*)ptr;
183
183
 
184
- RUBY_ASSERT(capture->running == 0);
185
-
186
184
  Fiber_Profiler_Stream_free(&capture->stream);
187
185
  Fiber_Profiler_Deque_free(&capture->calls);
188
186
 
@@ -1,6 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2025, by Samuel Williams.
4
+ # Copyright, 2025-2026, by Samuel Williams.
5
5
 
6
6
  require_relative "native"
7
+ require_relative "fork_handler"
8
+
9
+ module Fiber::Profiler
10
+ # Thread-local storage for the active profiler capture.
11
+ ::Thread.attr_accessor :fiber_profiler_capture
12
+
13
+ # Private module that wraps start/stop to manage thread-local storage.
14
+ module ThreadLocalCapture
15
+ # Start profiling and store the capture in the current thread's thread-local storage.
16
+ def start
17
+ result = super
18
+
19
+ if result
20
+ Thread.current.fiber_profiler_capture = self
21
+ end
22
+
23
+ return result
24
+ end
25
+
26
+ # Stop profiling and clear the capture from the current thread's thread-local storage.
27
+ def stop
28
+ result = super
29
+
30
+ if result
31
+ Thread.current.fiber_profiler_capture = nil
32
+ end
33
+
34
+ return result
35
+ end
36
+ end
37
+
38
+ private_constant :ThreadLocalCapture
39
+
40
+ # Represents a running profiler capture.
41
+ class Capture
42
+ prepend ThreadLocalCapture
43
+ end
44
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2026, by Samuel Williams.
5
+
6
+ module Fiber::Profiler
7
+ # Private module that hooks into Process._fork to handle fork events.
8
+ #
9
+ # If `Scheduler#process_fork` hook is adopted in Ruby 4, this code can be removed after Ruby < 4 is no longer supported.
10
+ module ForkHandler
11
+ def _fork(&block)
12
+ result = super
13
+
14
+ if result.zero?
15
+ # Child process: disable the profiler for the current thread
16
+ if capture = Thread.current.fiber_profiler_capture
17
+ begin
18
+ capture.stop
19
+ rescue
20
+ # Ignore errors - the profiler may be in an invalid state after fork
21
+ end
22
+ end
23
+ end
24
+
25
+ return result
26
+ end
27
+ end
28
+
29
+ private_constant :ForkHandler
30
+
31
+ # Hook into Process._fork to handle fork events automatically:
32
+ ::Process.singleton_class.prepend(ForkHandler)
33
+ end
@@ -7,6 +7,6 @@
7
7
  class Fiber
8
8
  # @namespace
9
9
  module Profiler
10
- VERSION = "0.5.0"
10
+ VERSION = "0.6.0"
11
11
  end
12
12
  end
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2025, by Samuel Williams.
4
+ # Copyright, 2025-2026, by Samuel Williams.
5
5
 
6
6
  require_relative "profiler/version"
7
7
  require_relative "profiler/native"
8
+ require_relative "profiler/fork_handler"
8
9
 
9
10
  module Fiber::Profiler
10
11
  # The default profiler to use, if any.
data/license.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
 
3
- Copyright, 2025, by Samuel Williams.
3
+ Copyright, 2025-2026, by Samuel Williams.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/readme.md CHANGED
@@ -18,6 +18,10 @@ Please see the [project documentation](https://socketry.github.io/fiber-profiler
18
18
 
19
19
  Please see the [project releases](https://socketry.github.io/fiber-profiler/releases/index) for all releases.
20
20
 
21
+ ### v0.6.0
22
+
23
+ - Fixed compatibility with `Process.fork`.
24
+
21
25
  ### v0.1.3
22
26
 
23
27
  - Improved performance when not profiling (when sampling is enabled).
@@ -36,6 +40,22 @@ We welcome contributions to this project.
36
40
  4. Push to the branch (`git push origin my-new-feature`).
37
41
  5. Create new Pull Request.
38
42
 
43
+ ### Running Tests
44
+
45
+ To run the test suite:
46
+
47
+ ``` shell
48
+ bundle exec sus
49
+ ```
50
+
51
+ ### Making Releases
52
+
53
+ To make a new release:
54
+
55
+ ``` shell
56
+ bundle exec bake gem:release:patch # or minor or major
57
+ ```
58
+
39
59
  ### Developer Certificate of Origin
40
60
 
41
61
  In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
data/releases.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Releases
2
2
 
3
+ ## v0.6.0
4
+
5
+ - Fixed compatibility with `Process.fork`.
6
+
3
7
  ## v0.1.3
4
8
 
5
9
  - Improved performance when not profiling (when sampling is enabled).
data.tar.gz.sig CHANGED
@@ -1,2 +1,3 @@
1
- ���I9?�8��3ŝy��m�ӗ<��TqT0+Hʎ��
2
- ���pc�7q��[��{�CJ���cg�W4�=���M����E���T?l�V�"IZ��� +���|�� ̛���>y�u3�t>C���|9�9���n�]`�b������(���Z���=�“9�~l�9�������6%^�G0��y*�̺:�_ܐ���b�x�b���QP�Sf���>�@T,��o��0�b�;X�o?�#�� ���IfO��^.��GI?��捰Eo�9p�Ԑ)9��ټ)�S�"�}�����: sr��7���V]
1
+ j��(��6���x��PU�@��� ǒ����t��h���1��x�e��:��Eaʩ̵�����at4�7�iB߆�ɬ�c���1��QsĹ��Y'ߘYg�r7=�-����0�z�ݐBL��#~��m�X�?����55�l�M�ڂE$��<( f���kX�H��`6ї(}��0��Q&<2_J�qV��3h���){���7 �� �G�
2
+
3
+ o��
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fiber-profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -43,6 +43,9 @@ extensions:
43
43
  - ext/extconf.rb
44
44
  extra_rdoc_files: []
45
45
  files:
46
+ - bake/fiber/profiler/analyze.rb
47
+ - context/getting-started.md
48
+ - context/index.yaml
46
49
  - ext/extconf.rb
47
50
  - ext/fiber/profiler/capture.c
48
51
  - ext/fiber/profiler/capture.h
@@ -55,6 +58,7 @@ files:
55
58
  - ext/fiber/profiler/time.h
56
59
  - lib/fiber/profiler.rb
57
60
  - lib/fiber/profiler/capture.rb
61
+ - lib/fiber/profiler/fork_handler.rb
58
62
  - lib/fiber/profiler/native.rb
59
63
  - lib/fiber/profiler/version.rb
60
64
  - license.md
@@ -73,14 +77,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
73
77
  requirements:
74
78
  - - ">="
75
79
  - !ruby/object:Gem::Version
76
- version: '3.2'
80
+ version: '3.3'
77
81
  required_rubygems_version: !ruby/object:Gem::Requirement
78
82
  requirements:
79
83
  - - ">="
80
84
  - !ruby/object:Gem::Version
81
85
  version: '0'
82
86
  requirements: []
83
- rubygems_version: 3.6.7
87
+ rubygems_version: 4.0.6
84
88
  specification_version: 4
85
89
  summary: A fiber stall profiler.
86
90
  test_files: []
metadata.gz.sig CHANGED
Binary file