Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ThreadPool#stats and adjust Server#stats to use it #3527

Merged
merged 1 commit into from
Oct 26, 2024

Conversation

MSP-Greg
Copy link
Member

Description

Many of the variables in ThreadPool are locked when changing their values. Current stats code may enter that lock more than once. See #3517 (comment).

This PR creates a ThreadPool#stats method that returns a hash of the stats data that comes from ThreadPool, using a single lock.

Your checklist for this pull request

  • I have reviewed the guidelines for contributing to this repository.
  • I have added (or updated) appropriate tests if this PR fixes a bug or adds a feature.
  • My pull request is 100 lines added/removed or less so that it can be easily reviewed.
  • If this PR doesn't need tests (docs change), I added [ci skip] to the title of the PR.
  • If this closes any issues, I have added "Closes #issue" to the PR description or my commit messages.
  • I have updated the documentation accordingly.
  • All new and existing tests passed, including Rubocop.

@MSP-Greg MSP-Greg requested a review from schneems October 17, 2024 15:38
@MSP-Greg
Copy link
Member Author

MSP-Greg commented Oct 17, 2024

A few questions:

There are several methods that can be removed with this. Should we mark then as deprecated as of Puma 7?

Several of current 'stats' tests check the generated 'stats' string. These have long, hard to read match strings/regexes. Are we concerned about the string representation, or should we be checking them as objects returned via JSON.parse?

In addition to #3517, I'd like to add two more items to stats, backlog_max, which would be the maximum size of the ThreadPool @todo array, and also something like selector_size_max, which would contain the maximum number of clients/sockets contained in the Reactor. Another question about these is whether they should be reset after every 'stats' call.

These look at Puma behavior when it may see 'bursts' of traffic, which is the main cause of the long-tail issue...

running: @spawned,
pool_capacity: @waiting (@max - @spawned)
}
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here's the approach i was thinking, in order to avoid repeating code (naming can change of course). WDYT?

def backlog_logic
  @todo.size
end
def backlog
  with_mutext { backlog_logic }
end
def stats
  with_mutex do
    { backlog: backlog_logic,
      ...
    }
  end
end

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, the three methods exist only so Server#stats can obtain the information. There is one exception, and that may be removed with work currently being looked at to help with the 'long tail' issue.

So, thanks for the example. As I mentioned, they may be deprecated and removed in Puma 7.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh gotcha, i thought others were used for business logic like busy_threads

lib/puma/server.rb Outdated Show resolved Hide resolved
Copy link
Contributor

@schneems schneems left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems good. Asked to remove a single extra whitespace line.

Copy link
Contributor

@jjb jjb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

concern: does existing test suite really test the behavior of stats method fully after this PR? could we, in this PR, remove the mutex from backlog, invoke the method from stats instead of copy/pasting the logic there, and keep things like that? (possibly moving the two methods into private in the future)

if we don't do that, suggestion: add comments above the methods which are now never invoked by puma code, indicating this, maybe linking to this PR, maybe saying maybe they should be deprecated in the future (or can the deprecation decision be made now in this PR?)

@MSP-Greg
Copy link
Member Author

concern: does existing test suite really test the behavior of stats method fully after this PR?

As mentioned in PR #3528, until all the stats hash values are unique, not really. The purpose of this code was to simplify gathering the metrics from ThreadPool, so Server isn't doing them in multiple method calls, currently with more than one lock.

Re issues like backlog, keeping code 'dry' is important, but calling single line methods is not a good idea, especially considering the future with YJIT, etc. When the issue comes up, I prefer comments.

Re all these stat related methods, the 'long-tail' issue may result in changes as to what metrics are used by Puma for request routing/processing. Hence, my opinion is to leave as is, and fix up for Puma v7.

@jjb
Copy link
Contributor

jjb commented Oct 23, 2024

Sorry, I should have been more clear (and should have checked first) - I assumed that pool_capacity, running, and backlog all had unit tests in addition to the (more like) integration tests in #3528, and worried that those would be deleted when those methods are retired, so we would lose the "behavior" tests - but looking now I see that there are no such tests (test_correct_waiting_count_for_killed_threads and test_append_queues_on_max use backlog but aren't specifically testing it.) so there isn't that risk in removing those methods eventually (can just swap in @todo.size for those two).

In any case - I think this PR is ready to go! (unless you want to add comments to, or even get the ball rolling on deprecating, those 3 methods in this PR.)

@MSP-Greg MSP-Greg merged commit 2482fac into puma:master Oct 26, 2024
147 checks passed
@MSP-Greg MSP-Greg deleted the 00-stats branch October 26, 2024 00:30
def stats
STAT_METHODS.map {|name| [name, send(name) || 0]}.to_h
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

STAT_METHODS is now only referenced from the test suite

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants