ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: "mame (Yusuke Endoh)" <noreply@ruby-lang.org>
To: ruby-core@ruby-lang.org
Subject: [ruby-core:105321] [Ruby master Feature#18176] Make Coverage suspendable
Date: Fri, 17 Sep 2021 06:41:10 +0000 (UTC)	[thread overview]
Message-ID: <redmine.issue-18176.20210917064110.18@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-18176.20210917064110.18@ruby-lang.org

Issue #18176 has been reported by mame (Yusuke Endoh).

----------------------------------------
Feature #18176: Make Coverage suspendable
https://bugs.ruby-lang.org/issues/18176

* Author: mame (Yusuke Endoh)
* Status: Open
* Priority: Normal
* Assignee: mame (Yusuke Endoh)
----------------------------------------
I'd like to add `Coverage.suspend`, `Coverage.resume`, and some methods.

## Synopsis

```
 1: # target.rb
 2: def foo
 3:   :foo
 4: end
 5:
 6: def bar
 7:   :bar
 8: end
 9:
10: def baz
11:   :baz
12: end
```

```
require "coverage"

# Similar to Coverage.start, but does not start the measurement itself
Coverage.setup(oneshot_lines: true)

load "target.rb"

foo              # This call is not counted
Coverage.resume  # Start the measurement
bar              # This call is counted
Coverage.suspend # Stop the measure
baz              # This call is not counted

# The result is only for Line 7, the body of method "bar"
p Coverage.result #=> {"target.rb"=>{:oneshot_lines=>[7]}}
```

## Background

The motivation is to divide modules for large web services. For web services with a long history, we tend to lose track of the dependencies between modules. Using this proposal and oneshot coverage, we can gather information about the code used to process a particular endpoint with almost no runtime cost. Gathering the information for some endpoints will give a hint to isolate the modules.

I've received similar requests in the past to make Coverage restartable but I didn't understand the need for it. (Sorry about that!) I heard directly from those who were actually in trouble in our company, and I finally understand. Also, the introduction of oneshot coverage, which can now be measured at almost no cost, has increased the demand for suspendable coverage.

## New APIs

* `Coverage.setup`: Almost the same as `Coverage.start` but does not start the measurement itself.
* `Coverage.resume`: Start/resume the coverage measurement.
* `Coverage.suspend`: Suspend the coverage measurement; it is restartable by using `Coverage.resume`.
* `Coverage.state`: Returns the current state: `:idle`, `:suspended`, and `:running`.

`Coverage.start(...)` is now the same as `Coverage.start(...); Coverage.resume`.
`Coverage.running?` is the same is `Coverage.state == :running`.

## Discussion

* Currently, I think `Coverage.suspend` makes sense only for oneshot coverage, but it supports traditional coverage too, for a unknown use case. However, I may disallow it if we find any problems.
* It is ideal to measure multiple oneshot coverage for each endpoint together, but it was difficult for me to implement it efficiently. My co-workers say that this feature is still valuable even with the limitation.
* Another idea is to use TracePoint. However, I'd like to introduce this feature to the coverage library because (1) the runtime cost of TracePoint seems not to be negligible according to our preliminary experiment, (2) we can use an ecosystem for oneshot coverage (e.g., https://github.com/riseshia/oneshot_coverage), and (3) the changeset for coverage is not so large.

## Implementation

https://github.com/ruby/ruby/pull/4856

Any comments are welcome.



-- 
https://bugs.ruby-lang.org/

       reply	other threads:[~2021-09-17  6:41 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-17  6:41 mame (Yusuke Endoh) [this message]
2021-10-25  8:49 ` [ruby-core:105777] [Ruby master Feature#18176] Make Coverage suspendable mame (Yusuke Endoh)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=redmine.issue-18176.20210917064110.18@ruby-lang.org \
    --to=ruby-core@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).