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

stats: add built-in log linear histogram support #3130

Merged

Conversation

ramaraochavali
Copy link
Contributor

@ramaraochavali ramaraochavali commented Apr 19, 2018

Signed-off-by: Rama [email protected]
Description:
Implements built-in log linear histogram.
Risk Level: High
Testing:
Unit, Integration and Manual testing.
Docs Changes:
NA
Release Notes:
Will create PR for version update once this is approved.
Fixes the issue #1965

@ramaraochavali ramaraochavali changed the title native log linear implementation stats: add built-in log linear histogram support Apr 19, 2018
@ramaraochavali
Copy link
Contributor Author

@mattklein123 @jmarantz @mrice32 created this fresh PR with single commit so that we can continue here.

const std::vector<double>& supported_quantiles_ref =
histogram->intervalStatistics().supportedQuantiles();
for (size_t i = 0; i < supported_quantiles_ref.size(); ++i) {
summary.push_back(fmt::format("P{}({},{})", 100 * supported_quantiles_ref[i],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mattklein123 capturing your question from the previous PR, so that we can continue the discussion.
Do we think cumulative has much benefit? I can't imagine it being very useful from a debugging perspective so I wonder if we should just drop it here? Thoughts?
Here is the current format
cluster.time.upstream_rq_time: P0(0,0) P25(0,0) P50(0,0) P75(0,1.015) P90(1.06387,1.07194) P95(1.08525,1.09093) P99(2.04331,2.07759) P99.9(4.08333,23) P100(23,140)

Copy link
Contributor Author

@ramaraochavali ramaraochavali Apr 19, 2018

Choose a reason for hiding this comment

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

I think I can go either away here. It would be useful to compare against cumulative some times to see how much actually has it changed in the interval we are looking at.
Couple of options

  1. print all interval histograms first like this
    cluster.time.upstream_rq_time: P0 0 P25 0 P50 0 P75 0 P90 1.06387 P9 1.08525 P99 2.04331 P99.9 4.08333 P100 23
    and after all are done, we add a line like "cumulative histograms" and print all cumulative histograms.
  2. print interval and cumulative simultaneously as shown below
cluster.time.upstream_rq_time: P0 0 P25 0 P50 0 P75 0 P90 1.06387  P9 1.08525  P99 2.04331 P99.9 4.08333 P100 23 (Interval)
cluster.time.upstream_rq_time: P0 0 P25 0 P50 0 P75 0 P90 1.06387  P9 1.08525  P99 2.04331 P99.9 4.08333 P100 23 (Cumulative) 

Copy link
Member

Choose a reason for hiding this comment

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

I'm fine with whatever. Let's just keep what you have. We don't guarantee this format here so we can always change it later. It would be nice to document this though. Can you add some docs (and fixup the text about no histogram support) here? https://github.com/envoyproxy/envoy/blame/master/docs/root/operations/admin.rst#L184

Also, can you add a release note about this awesome feature?

Copy link
Contributor

@jmarantz jmarantz left a comment

Choose a reason for hiding this comment

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

This is looking really close. The tests are much easier to read now, and really there's just a few nits left, with one possible issue with atomics vs condvars.

This is the first time I've really looked at threading inside Envoy and its test infrastructure so hopefully I didn't mislead you. @mattklein123 can correct :)

Note also that @ramaraochavali use of condvar in the runOnAllThreads test was suggested by me in one of the previous PRs. If there's a better pattern in the Envoy codebase or test infra, please let me know.


bool ParentHistogramImpl::used() const {
std::unique_lock<std::mutex> lock(merge_lock_);
return usedWorker();
Copy link
Contributor

Choose a reason for hiding this comment

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

fwiw the convention I've seen is use the name usedLockHeld() for this pattern. What you have is fine too. More important is for us to start adding thread annotation but AFAIK it doesn't do anything in Envoy builds yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am fine with changed name - @mattklein123 what do you think?

Copy link
Member

Choose a reason for hiding this comment

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

Sure SGTM.

@@ -496,6 +514,40 @@ std::string AdminImpl::statsAsJson(const std::map<std::string, uint64_t>& all_st
stat_obj.AddMember("value", stat_value, allocator);
stats_array.PushBack(stat_obj, allocator);
}

for (Stats::ParentHistogramSharedPtr histogram : all_histograms) {
Copy link
Contributor

Choose a reason for hiding this comment

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

const Stats::ParentHistogramSharedPtr& histogram

class HistogramTest : public testing::Test, public RawStatDataAllocator {
public:
void SetUp() override {
InSequence s;
Copy link
Contributor

Choose a reason for hiding this comment

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

I suspect this actually belongs in the class declaration so that its directives extend to the test-methods, rather than just SetUp().

EXPECT_CALL(*this, free(_));
}

std::vector<uint64_t> h1_cumulative_values, h2_cumulative_values, h1_interval_values,
Copy link
Contributor

Choose a reason for hiding this comment

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

underscore suffixes for these member vars.

std::vector<uint64_t> h1_cumulative_values, h2_cumulative_values, h1_interval_values,
h2_interval_values;

typedef std::map<std::string, Stats::ParentHistogramSharedPtr> NameHistogramMap;
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for doing this! Make the tests much easier to read.

nit: typedefs at top of class

https://google.github.io/styleguide/cppguide.html#Declaration_Order

I admit I don't do this all of the time because sometimes it's got only one use in the declaration, right below it. But here your usage is broader, so for readability it makes sense to move to the top of the class.

stat_flush_timer_->enableTimer(config_->statsFlushInterval());
// TODO(ramaraochavali): consider adding different flush interval for histograms.
stats_store_.mergeHistograms([this]() -> void {
HotRestart::GetParentStatsInfo info;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm curious what happens here if the system shuts down and deletes the server InstanceImpl before the lambda runs here. I think the answer is that the shutdown will prevent this lambda from running, per a comment I saw elsewhere. I think it'd be nice to note that here as well, perhaps pointing to the doc for runOnAllThreads. And I think this guarantee is due to the semantics of main_thread_dispatcher_->post, which I haven't looked at yet :)


std::list<ParentHistogramSharedPtr> histogram_list = store_->histograms();

histogram_t* hist1_cumulative = hist_alloc();
Copy link
Contributor

Choose a reason for hiding this comment

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

this repeated 4-line stanza could be factored out into a test helper method:
histogram_t* makeHistogram(values) { ... }

* that can be asserted later.
*/
uint64_t validateMerge() {
std::atomic<bool> merge_called{false};
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this needs to be, or should be, atomic. The done callback is going to be called exactly once.

Whenever I see atomics I go into hyper-paranoia mode because it's easy to create logical races with them, so I'd rather not have them declared as atomic if it's not (necessary and sufficient).

In this case, the race would be if mergeHistograms ran on another thread, then the EXPECT_TRUE would be a logical race independent of whether the data is atomic or not. In that case, the main remedy I'm aware of to allow this test to block until completion is using a condvar as you did elsewhere.

If this test always completes before mergeHistogram returns, then you don't need the atomic. If it doesn't, the atomic isn't sufficient.

@mattklein123 I'm wondering if the unit test infrastructure serializes threads and therefore I'm being overly paranoid about wanting to block test progress until they complete. FWIW In the past I've done unit testing with threads in full force, but then had common test infrastructure primitives to help quiesce before expecting results.

bool all_threads_complete_;
} thread_local_data;

tlsptr->runOnAllThreads(
Copy link
Contributor

Choose a reason for hiding this comment

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

qq on this, now that I think of it...it's not clear how many threads there actually are when this is tested. Should we ensure there are 10 real threads running in this test?

Copy link
Contributor Author

@ramaraochavali ramaraochavali Apr 19, 2018

Choose a reason for hiding this comment

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

currently it is 1. The thing that is being verified here is whether the main call back is called after the all post callbacks are executed and it is called as per the expected number of times asserted via thread_local_calls_. Both the things are happening.
The threads here are MockDispatcher instances so I am not really sure having 10 threads helps. Let @mattklein123 review this test and if he suggests it helps to add 10 threads, I will surely add tomorrow.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK. If there is only one thread in the system I'm pretty convinced we need no condvars or atomics.

But since this is a test of threading infrastructure, I would hope we'd use real threads for this.

Copy link
Member

Choose a reason for hiding this comment

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

The test you have written only has a single thread. It's not useless, but it would be nice to have at least one other real thread. See the test immediately below this one ("Dispatcher"). You should be able to add another real thread and test the real behavior with 1 or more real threads. In that case, you will definitely need the lock/atomic/condvar to have the test correctly work.

The way I would structure the test is to startup 1 or more threaded dispatchers in blocking mode, then when you get the post event, just exit the dispatch loop. Then back on the main thread, you can wait for all worker threads to exit with join, etc.

Copy link
Contributor Author

@ramaraochavali ramaraochavali Apr 20, 2018

Choose a reason for hiding this comment

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

@mattklein123 I implemented similar to what you have described. In the unit testing setup, the post to main_dispatcher is not actually posting with DispatcherImpl as expected. I tried to post on main_dispatcher by just simply calling main_dispatcher.post() on Dispatcher test also but it is not posting correctly.. So I changed the existing test to test the sequence of callbacks and I think integration tests would any way test the posting part.

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

This is absolutely awesome. So excited for this to land. Just some random comments but I think we are mostly good to go after these are cleaned up. Thanks!

virtual ~ParentHistogram() {}

/**
* This method is called during the main stats flush process for each of the histogram and used
Copy link
Member

Choose a reason for hiding this comment

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

nit: "each of the histograms"

* Run a callback on all registered threads with a barrier. A shutdown initiated during the
* running of the PostCBs may prevent all_threads_complete_cb from being called.
* @param cb supplies the callback to run on each thread.
* @param all_threads_complete_cb supplies the callback to run on main thread after threads are
Copy link
Member

Choose a reason for hiding this comment

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

"after cb has been run on all registered threads."

std::string HistogramStatisticsImpl::summary() const {
std::vector<std::string> summary;
const std::vector<double>& supported_quantiles_ref = supportedQuantiles();
for (size_t i = 0; i < supported_quantiles_ref.size(); ++i) {
Copy link
Member

Choose a reason for hiding this comment

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

summary.reserve(supported_quantiles_ref.size());

*/
HistogramStatisticsImpl(const histogram_t* histogram_ptr);

std::string summary() const override;
Copy link
Member

Choose a reason for hiding this comment

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

nit: // HistogramStatistics above this line.

const std::vector<double>& supportedQuantiles() const override;
const std::vector<double>& computedQuantiles() const override { return computed_quantiles_; }

void refresh(const histogram_t* new_histogram_ptr);
Copy link
Member

Choose a reason for hiding this comment

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

nit: Move this below 376 (above interface overrides for clarity)

const std::vector<double>& supported_quantiles_ref =
histogram->intervalStatistics().supportedQuantiles();
for (size_t i = 0; i < supported_quantiles_ref.size(); ++i) {
summary.push_back(fmt::format("P{}({},{})", 100 * supported_quantiles_ref[i],
Copy link
Member

Choose a reason for hiding this comment

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

I'm fine with whatever. Let's just keep what you have. We don't guarantee this format here so we can always change it later. It would be nice to document this though. Can you add some docs (and fixup the text about no histogram support) here? https://github.com/envoyproxy/envoy/blame/master/docs/root/operations/admin.rst#L184

Also, can you add a release note about this awesome feature?

bool all_threads_complete_;
} thread_local_data;

tlsptr->runOnAllThreads(
Copy link
Member

Choose a reason for hiding this comment

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

The test you have written only has a single thread. It's not useless, but it would be nice to have at least one other real thread. See the test immediately below this one ("Dispatcher"). You should be able to add another real thread and test the real behavior with 1 or more real threads. In that case, you will definitely need the lock/atomic/condvar to have the test correctly work.

The way I would structure the test is to startup 1 or more threaded dispatchers in blocking mode, then when you get the post event, just exit the dispatch loop. Then back on the main thread, you can wait for all worker threads to exit with join, etc.

class HistogramTest : public testing::Test, public RawStatDataAllocator {
public:
typedef std::map<std::string, Stats::ParentHistogramSharedPtr> NameHistogramMap;
InSequence s;
Copy link
Member

Choose a reason for hiding this comment

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

Does this make all tests run as in sequence??? Wow, neat trick. I wish I had already known this. :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Not exactly. https://github.com/google/googletest/blob/master/googlemock/docs/ForDummies.md

By creating an object of type InSequence, all expectations in its scope are put into a sequence and have to occur sequentially. Since we are just relying on the constructor and destructor of this object to do the actual work, its name is really irrelevant.

} else {
const std::string format_key = params.begin()->first;
const std::string format_value = params.begin()->second;
if (format_key == "format" && format_value == "json") {
response_headers.insertContentType().value().setReference(
Http::Headers::get().ContentTypeValues.Json);
response.add(AdminImpl::statsAsJson(all_stats));
response.add(AdminImpl::statsAsJson(all_stats, server_.stats().histograms()));
Copy link
Member

Choose a reason for hiding this comment

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

Can you put a TODO in here somewhere to add summary histogram output for Prometheus? I think it's a trivial change and once that is done we basically have full Prometheus support which is awesome.

MockParentHistogram();
~MockParentHistogram();

// Note: cannot be mocked because it is accessed as a Property in a gmock EXPECT_CALL. This
Copy link
Member

Choose a reason for hiding this comment

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

I've never heard of an issue like this before. Can you explain a bit more how this happens?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is just copied from MockHistogram, I am not sure about these details. Sorry :-)

Copy link
Member

@mrice32 mrice32 left a comment

Choose a reason for hiding this comment

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

This looks awesome - especially the threading work! I left a few nits and one concern I have about the threading model.

if (names.insert(hist_name).second) {
ret.push_back(parent_hist);
} else {
ENVOY_LOG(warn, "duplicate histogram {}.{}: data loss will occur on output", scope->prefix_,
Copy link
Member

Choose a reason for hiding this comment

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

nit: Isn't the prefix assumed to have the trailing . included? So shouldn't this be duplicate histogram {}{}:?

bool any_tls_used = false;
for (const TlsHistogramSharedPtr& tls_histogram : tls_histograms_) {
if (tls_histogram->used()) {
any_tls_used = true;
Copy link
Member

Choose a reason for hiding this comment

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

nit: why not just get rid of the local variable and just return true here and false after the loop?

metric->set_timestamp_ms(std::chrono::system_clock::now().time_since_epoch().count());
auto* summary_metric = metric->mutable_summary();
const Stats::HistogramStatistics& hist_stats = histogram.intervalStatistics();
size_t index = 0;
Copy link
Member

Choose a reason for hiding this comment

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

nit: I think this would be a bit more readable and less bug-prone if you used a normal for loop (for(size_t i = 0;...)) and used the index for both vectors rather than just one.

}

void ThreadLocalHistogramImpl::recordValue(uint64_t value) {
hist_insert_intscale(histograms_[current_active_], value, 0, 1);
Copy link
Member

@mrice32 mrice32 Apr 19, 2018

Choose a reason for hiding this comment

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

Disclaimer: I may be totally missing something here or this may have already been discussed.

High-level question: is there any guarantee that a histogram produced by the store/scope will only be used in the thread in which it is created? This implementation appears to depend on that guarantee. IIUC, this is not assumed for any of the existing stats or the old histograms. If this is assumed in this case, we need to be careful about how the histogram macros are currently used and be sure to clearly document this restriction.

For example:

auto my_hist = some_scope.histogram(some_name);
.
.
.
// Does this have to be in the same thread as the call above?
my_hist.recordValue(5);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

for each histogram created we have ThreadLocal equivalent that is updated in that thread and and ParentHistogram that holds the summary across all the threads. So I think it is not an issue.

Copy link
Member

@mrice32 mrice32 Apr 20, 2018

Choose a reason for hiding this comment

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

Sorry, I think that's exactly my concern. The thread from which you call Histogram& hist = some_scope.histogram(some_name); is assumed to be the same thread that will ultimately call hist.recordValue(). This assumption doesn't generally hold for stats. Many stats are created in the main thread and then passed around to other threads to modify their values since all the existing stats objects are completely thread safe. See this stats struct as an example: https://github.com/envoyproxy/envoy/blob/master/source/common/http/conn_manager_impl.h#L405. It is created in the HttpConnectionManagerConfig, which is initialized in the main thread. Then it is passed to all of the HttpConnectionManagers that are created for each request (can be on any worker thread). The worker threads are able to freely mutate the stats IIUC.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, yes. Great catch @mrice32. This is broken, at least for how we commonly use histograms. I think the best option to fix is probably to always return back a parent/main thread histogram, and then have recordValue() internally redirect to the TLS version (and create it if needed). I can have a look more later about other options.

Copy link
Member

Choose a reason for hiding this comment

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

Alright, I looked at the code again. Here is my suggestion on how to fix this (though I'm going to admit that this change is complicated enough I'm having trouble doing the design without also being able to try some stuff out via coding, so if it comes to that I can help out). It's going to require some code-rejiggering, but I don't think it's going to end up being too terribly difficult, and it will leave us in a cleaner/better place.

  1. When you return a Histogram from the thread local store, what you will actually return effectively is the parent histogram, not the TLS histogram.
  2. When recordValue() is called on the parent, at that point, you will do the TLS lookup/cache add, and then call recordValue() on the actual TLS version.

This should be pretty easily doable by just changing the flow of the histogram acquisition function that you have now.

Copy link
Member

@mrice32 mrice32 Apr 20, 2018

Choose a reason for hiding this comment

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

@mattklein123 SGTM, I like that solution. I was trying to think of a way to do it without doing a cache lookup for every recordValue() call, but I don't think it would be possible without a TLS slot per histogram, and TLS isn't really built for that sort of scaling IIUC (and cache lookups are pretty cheap).

@jmarantz Not sure. I'm surprised that tsan didn't get upset about this in one of the existing integration tests.

Copy link
Member

Choose a reason for hiding this comment

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

I was trying to think of a way to do it without doing a cache lookup for every recordValue() call

I think in the future we could add some type of "direct TLS access" histogram for use cases in which the user knows they are safe, but IMO I wouldn't worry about it for now and we can track as a future perf improvement...

Copy link
Member

Choose a reason for hiding this comment

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

@ramaraochavali one other thing we should do here is keep track of the thread ID that the TLS histograms are created on and make sure that recordValue() is only called on that same thread. You could add ASSERTs along those lines pretty easily, and it would also help document the threading model.

Copy link
Contributor Author

@ramaraochavali ramaraochavali Apr 21, 2018

Choose a reason for hiding this comment

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

@mattklein123 @mrice32 I have added a tlsHistogram method in the ScopeImpl that creates ThreadLocalHistogram since the ScopeImpl has all the things needed for putting in scope cache etc. It is working fine. Can you PTAL? I think we should be good with this.

@mattklein123 I have added the ASSERT that you mentioned.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mrice32 are you fine with this change?

* histograms, one to collect the values and other as backup that is used for merge process. The
* swap happens during the merge process.
*/
class ThreadLocalHistogram : public virtual Histogram {
Copy link
Member

Choose a reason for hiding this comment

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

It seems strange that this interface is under source/ rather than include/, especially since ParentHistogram is under include/ and its docs implicitly reference the thread local histograms.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It was discussed that we do not want to expose the ThreadLocalHistogram in the stats interface as it is implementation detail. I would adjust the docs of ParentHistogram not to refer this in stats.h definition.

Copy link
Member

Choose a reason for hiding this comment

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

That makes sense. But in that same vein, why do we need to expose ParentHistogram in the interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is because the rest of the code like admin, server and stats sinks especially Metrics Service sink use it to push data to sinks.

Copy link
Member

Choose a reason for hiding this comment

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

Ahhh, I see. Thanks for the explanation. Sorry to keep pulling at this, as it's really just a nit, but I do have one last question - why do we need the abstract base class? It seems that all uses (including TlsHistogramSharedPtr) explicitly reference the ThreadLocalHistogramImpl. Do you think that we'll ultimately have other TLS histogram implementations? If so, maybe we should use the base class in those places?

Copy link
Member

Choose a reason for hiding this comment

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

I think you can just remove this interface entirely. Is it even needed? I would just fold it all into the implementation below which is specific to this thread_local_store implementation?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. We can do that. I have changed. PTAL.


tls_.shutdownGlobalThreading();
tls_.shutdownThread();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

At a minimum, can you leave a TODO to get the multi-thread version test running, along with more detailed information about why your previous attempt didn't work?

struct {
uint64_t thread_local_calls_{0};
bool all_threads_complete_ = false;
} thread_local_data;
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this data is thread-local. Maybe just rename the struct to be 'thread_status'

Signed-off-by: Rama <[email protected]>
Signed-off-by: Rama <[email protected]>
Copy link
Contributor

@jmarantz jmarantz left a comment

Choose a reason for hiding this comment

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

Diving in a bit deeper to the semantics....

Histogram& ThreadLocalStoreImpl::ScopeImpl::tlsHistogram(const std::string& name) {
// Here prefix will not be considered because, by the time ParentHistogram calls this method
// during recordValue, the prefix is already attached to the name.
TlsHistogramSharedPtr* tls_ref = nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

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

suggest early-exit here if parent is shutting down or doesn't have TLS, simplifying conditionals below.

It's actually a little strange to me that you allocate a histogram object even if you are shutting down. WDYT of returning a Histogram* that's allowed to be nullptr and handling that case at the call-site?

Alternative what you have is OK but deserves some comments for the call-during-shutdown case.

I'm also not sure when parent.tls_ might be null.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It follows the same logic as counter(), histogram() etc are followed. I added the comment here as well.

@@ -75,6 +99,31 @@ void ThreadLocalStoreImpl::shutdownThreading() {
shutting_down_ = true;
}

void ThreadLocalStoreImpl::mergeHistograms(PostMergeCb merge_complete_cb) {
if (!shutting_down_) {
Copy link
Contributor

Choose a reason for hiding this comment

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

mergeHistograms is async. So I wonder if you should keep track of whether there's one in progress, and skip merging in that case. I think the behavior if you induce two or three merges in a row before merge_complete_cb, the behavior may be hard to reason about.

In that case it may be sufficient to simply drop the callback; that would seem to work well for the call-site in InstanceImpl::flushStats()

Copy link
Contributor Author

@ramaraochavali ramaraochavali Apr 22, 2018

Choose a reason for hiding this comment

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

I do not think there would be two merges happening in parallel unless the merge takes abnormally long. It is called from flushStats which is invoked for every stats flush interval default value of which is 5 sec. This might happen if the flush interval is configured very low, may be less than sec or few milliseconds. So I think the tracking complication is not required here.

Copy link
Contributor

Choose a reason for hiding this comment

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

All it takes is for a thread to not get scheduled for a few seconds because the machine is busy, and this will be an issue. Don't you think it's worth checking?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure if it is really required or not but I see no harm in adding that check. Added. PTAL.

Copy link
Member

@mrice32 mrice32 Apr 22, 2018

Choose a reason for hiding this comment

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

I don't think this can happen with how we're using this method since the timer is only rescheduled in the last line of the merge_complete_cb, which is called only after all the merging is done. (Feel free to correct me if I'm misunderstanding the flow.)

If we imagine that this method may be used in other circumstances, I think a check like this could make sense, but this method has a pretty specific use case. Maybe instead we could leave out the check, but document how this method should be used (it can only be called again once the passed in callback is called)? We could still keep track of whether a merge is in progress and just ASSERT this check rather than branch on it. Not super opinionated, but it just sometimes makes code (especially complicated code :) ) less readable when inactive constraints are used in branches.

Copy link
Contributor

Choose a reason for hiding this comment

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

@mrice32 I think you are probably right, but there are two call-sites to flushStats() from server.cc. It's not immediately obvious to me that there may never be any other initiators. That is a private method now.

I think this is a very cheap check to add, to avoid having to think too hard about what very confusing (and possibly crashy) behavior might arise from having two or three concurrent mergeHistogram calls running. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mrice32 After pushed this I also realized that the timer is rescheduled only at the last line of the merge_complete_cb. I left it because it does not harm having this as it is safe and cheap trick as @jmarantz mentioned.

Copy link
Member

Choose a reason for hiding this comment

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

That's fair - I think the check makes sense. But I'm somewhat opposed to the idea of having concurrent merges appear as if they are part of the normal program flow and no-op when they happen. I would personally prefer to document how the method should be used and ASSERT(!merge_in_progress_). Anyway, either way is fine, that's just my personal preference. In either case, I think the behavior should be clearly documented in the declaration.

Copy link
Contributor

Choose a reason for hiding this comment

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

ASSERT would be OK with me. Is there an Envoy equivalent to

if (cond) {
  LOG(DFATAL) << "error message";
}

Where in release-builds this will log an error, and in debug builds it will also abort?

And in any case documenting how the methods should be used would be great.

Copy link
Contributor Author

@ramaraochavali ramaraochavali Apr 23, 2018

Choose a reason for hiding this comment

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

ok. I have added the ASSERT and updated the documentation of this method. PTAL.

InstanceUtil::flushCountersAndGaugesToSinks(config_->statsSinks(), stats_store_);
stat_flush_timer_->enableTimer(config_->statsFlushInterval());
// A shutdown initiated before this callback may prevent this from being called as per
// the semantics documented in ThreadLocal's runAllThreads method.
Copy link
Contributor

Choose a reason for hiding this comment

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

runOnAllThreads

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed

std::unique_lock<std::mutex> lock(merge_lock_);
if (usedLockHeld()) {
hist_clear(interval_histogram_);
for (const TlsHistogramSharedPtr& tls_histogram : tls_histograms_) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Matt commented earlier that you could capture the histogram-array and then unlock before doing the expensive merge. I'm not actually sure what would contend with merge_lock_ though, so I don't know how critical it is in practice. But a comment or TODO anyway would be good.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have added a comment explaining why it is not a big deal.

}
std::vector<Tag> tags;
std::string tag_extracted_name = parent_.getTagsForName(name, tags);
TlsHistogramSharedPtr hist_tls_ptr(
Copy link
Contributor

Choose a reason for hiding this comment

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

auto hist_tls_ptr = std::make_shared<ThreadLocalHistogramImpl>(...)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed


void ParentHistogramImpl::recordValue(uint64_t value) {
Histogram& tls_histogram = tlsScope_.tlsHistogram(name());
tls_histogram.recordValue(value);
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems reasonable to drop value if called during shutdown, and you make the change to allow a nullptr return I suggested elsewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure if we want to drop the value here. In the earlier histogram implementation also we are not dropping the value

void recordValue(uint64_t value) override { parent_.deliverHistogramToSinks(*this, value); }
. Keeping same semantics is better.

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it. The pattern you have is consistent with counters which have a lot of mileage. Looks great, thanks.

void ParentHistogramImpl::recordValue(uint64_t value) {
Histogram& tls_histogram = tlsScope_.tlsHistogram(name());
tls_histogram.recordValue(value);
parent_.deliverHistogramToSinks(*this, value);
Copy link
Contributor

Choose a reason for hiding this comment

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

Some commentary here would help. Are we really going to deliver complete histograms to sinks every time a value is recorded? That seems like it might be slow, and we should deliver histogram to sinks periodically. I may be off-base here as I am still not a master of the stat-sink architecture :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This does not deliver the entire histogram to stats sinks. Here we are actually delivering a single value to the stats sinks. This just calls onHistogramCompleted method of stats sinks which sinks could use to plug-in their histogram computations similar to how statsd does.

Copy link
Contributor

Choose a reason for hiding this comment

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

Cool, thanks for the explanation. That makes sense.

}

void ThreadLocalHistogramImpl::merge(histogram_t* target) {
const uint64_t other_histogram_index = otherHistogramIndex();
Copy link
Contributor

Choose a reason for hiding this comment

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

optional microoptimization: capture the histogram in a temp rather than the index:

histogram_t** other_histogram = &histograms_[otherHistogramIndex()];
hist_accumulate(target, other_histogram, 1);
hist_clear(target, *other_histogram);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks for this. changed.

// Here we could copy all the pointers to TLS histograms in the tls_histogram_ list,
// then release the lock before we do the actual merge. However it is not a big deal
// because the tls_histogram merge is not that expensive as it is a single histogram
// merge and adding TLS histograms is rare.
Copy link
Contributor

Choose a reason for hiding this comment

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

OK, sounds good. One thing to look out for in the future is contention with used(), but I don't have a feel for how often that gets called.

Copy link
Contributor

@jmarantz jmarantz left a comment

Choose a reason for hiding this comment

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

From my perspective this code looks great now! Thanks for all the work.

I think follow-up is required on:

  • unit testing with multiple threads
  • testing under load
  • a system test

class HistogramTest : public testing::Test, public RawStatDataAllocator {
public:
typedef std::map<std::string, Stats::ParentHistogramSharedPtr> NameHistogramMap;
InSequence s;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: move the InSequence declaration down to bottom of the class declaration with all the other member vas.

Copy link
Member

@mrice32 mrice32 left a comment

Choose a reason for hiding this comment

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

The new tls histogram setup looks good to me - I just have a few comments about thread-local caching.

/**
* Class used to create ThreadLocalHistogram in the scope.
*/
class TlsScope : public Scope {
Copy link
Member

Choose a reason for hiding this comment

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

Is there any reason we can't just add tlsHistogram() to the Scope interface and remove this class?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As per the general guideline we are taking in this design about not exposing ThreadLocal's to stats interface, I have added this class to specifically to have that method.

Copy link
Member

Choose a reason for hiding this comment

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

When I was first thinking about a solution here, my initial thinking was to basically do what @mrice32 proposes. I do think in the future we will want to do that. Basically, if the user knows they are in thread local context they can fetch the histogram from TLS directly. There are already cases in the code base which would benefit from this. E.g., any dynamic histogram lookups (router dynamic stats for example). I would be fine doing this change now. Though, given the complexity of this change, I would also be fine deferring to a follow up. If we do a follow up can you add a TODO that we should allow direct TLS access for the advanced consumer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mattklein123 I will defer this to a follow-up PR. added TODO.

Copy link
Member

Choose a reason for hiding this comment

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

SGTM.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mattklein123 can you point me to code samples that use direct TLS if the user is in thread local context? I will look at them and see If I can make that change?

Copy link
Member

Choose a reason for hiding this comment

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

@ramaraochavali any pattern like here: https://github.com/envoyproxy/envoy/blob/master/source/common/http/codes.cc#L82 where we dynamically grab a histogram and immediately record it. We could skip a double TLS lookup in this case if we offered a tlsHistogram() accessor. I think it would be pretty easy to do, but let's obviously sort out all of our other issues first. :) (Maybe open an issue to track.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure :-). With the finding we had yesterday I am hoping that they would comeback soon with the solution.

Histogram& ThreadLocalStoreImpl::ScopeImpl::tlsHistogram(const std::string& name) {
// See comments in counter() which explains the logic here.

// Here prefix will not be considered because, by the time ParentHistogram calls this method
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for pointing this out - could we document this in the base class header since it diverges from the behavior of the other 3 stat creation methods?

@@ -204,29 +255,130 @@ Histogram& ThreadLocalStoreImpl::ScopeImpl::histogram(const std::string& name) {
// See comments in counter(). There is no super clean way (via templates or otherwise) to
// share this code so I'm leaving it largely duplicated for now.
std::string final_name = prefix_ + name;
HistogramSharedPtr* tls_ref = nullptr;
std::unique_lock<std::mutex> lock(parent_.lock_);
ParentHistogramImplSharedPtr& central_ref = central_cache_.histograms_[final_name];
Copy link
Member

Choose a reason for hiding this comment

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

Why not have a thread-local cache for parents that we check before going to the central cache? There are two ways we could do this:

  1. Store a reference to the parent in the tls histogram, try to grab the tls histogram from its thread-local cache, and grab the parent from it if it exists.
  2. Create a thread-local cache just for the parent histograms that is totally distinct from the thread-local cache for tls histograms.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added TLS cache via #2. Please check once.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks @mrice32 for guidance here, this is the implementation I was expecting. Awesome work everyone!

TlsHistogramSharedPtr hist_tls_ptr = std::make_shared<ThreadLocalHistogramImpl>(
name, std::move(tag_extracted_name), std::move(tags));

ParentHistogramImplSharedPtr& central_ref = central_cache_.histograms_[name];
Copy link
Member

Choose a reason for hiding this comment

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

Since this is always called from the parent histogram, could we just pass the parent in rather than looking it up in the cache?

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

I think we are ready to rock and roll here. A few final comments from me. Awesome!

aggregation. This command is very useful for local debugging. See :ref:`here <operations_stats>`
for more information.
Outputs all statistics on demand. This command is very useful for local debugging.
Histograms will output the computed quantiles i.e P0,P25,P50,P75,P90, P99, P99.9 and P100.
Copy link
Member

Choose a reason for hiding this comment

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

nit: consistent single space after commas.

ParentHistogramImpl::ParentHistogramImpl(const std::string& name, Store& parent, TlsScope& tlsScope,
std::string&& tag_extracted_name, std::vector<Tag>&& tags)
: MetricImpl(name, std::move(tag_extracted_name), std::move(tags)), parent_(parent),
tlsScope_(tlsScope), interval_histogram_(hist_alloc()), cumulative_histogram_(hist_alloc()),
Copy link
Member

Choose a reason for hiding this comment

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

nit: s/TlsScope_/tls_scope_

/**
* Class used to create ThreadLocalHistogram in the scope.
*/
class TlsScope : public Scope {
Copy link
Member

Choose a reason for hiding this comment

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

When I was first thinking about a solution here, my initial thinking was to basically do what @mrice32 proposes. I do think in the future we will want to do that. Basically, if the user knows they are in thread local context they can fetch the histogram from TLS directly. There are already cases in the code base which would benefit from this. E.g., any dynamic histogram lookups (router dynamic stats for example). I would be fine doing this change now. Though, given the complexity of this change, I would also be fine deferring to a follow up. If we do a follow up can you add a TODO that we should allow direct TLS access for the advanced consumer?

@@ -401,18 +401,34 @@ Http::Code AdminImpl::handlerStats(absl::string_view url, Http::HeaderMap& respo
all_stats.emplace(gauge->name(), gauge->value());
}

for (const Stats::ParentHistogramSharedPtr& histogram : server_.stats().histograms()) {
std::vector<std::string> summary;
Copy link
Member

Choose a reason for hiding this comment

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

reserve() here also

@ramaraochavali
Copy link
Contributor Author

@mattklein123 addressed your comments. Should be good here. PTAL.

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

LGTM, I'm going to smoke test this at Lyft later just to be on the safe side. Thank you for your hard work here!

Copy link
Member

@mrice32 mrice32 left a comment

Choose a reason for hiding this comment

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

Awesome stuff!

@mattklein123
Copy link
Member

Smoke test looks good. This is super awesome. Looking forward to some of the cool follow ups we can do based on this work.

@mattklein123 mattklein123 merged commit 9a1e49f into envoyproxy:master Apr 23, 2018
@ramaraochavali ramaraochavali deleted the envoy_native_histogram_impl branch April 24, 2018 03:02
mattklein123 added a commit that referenced this pull request Apr 26, 2018
htuch pushed a commit that referenced this pull request May 3, 2018
This change unreverts:
#3130
#3183
#3219
Also fixes #3223

Please see the 2nd commit for the actual changes. The changes are:

Bring in a new histogram library version with the fix (and more debug
checking).
Fix a small issue with scope iteration during merging.
Remove de-dup for histograms until we iterate to shared
storage for overlapping scope histograms. Personally, I found
this very confusing when debugging and I think the way I changed
it is better for now given the code we have.

Signed-off-by: Matt Klein <[email protected]>
phlax pushed a commit that referenced this pull request Jul 15, 2024
…2 updates (#35076)

Bumps the pip group in /examples/grpc-bridge/client with 2 updates:
[certifi](https://github.com/certifi/python-certifi) and
[urllib3](https://github.com/urllib3/urllib3).

Updates `certifi` from 2023.7.22 to 2024.7.4
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/certifi/python-certifi/commit/bd8153872e9c6fc98f4023df9c2deaffea2fa463"><code>bd81538</code></a>
2024.07.04 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/295">#295</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/06a2cbf21f345563dde6c28b60e29d57e9b210b3"><code>06a2cbf</code></a>
Bump peter-evans/create-pull-request from 6.0.5 to 6.1.0 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/294">#294</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/13bba02b72bac97c432c277158bc04b4d2a6bc23"><code>13bba02</code></a>
Bump actions/checkout from 4.1.6 to 4.1.7 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/293">#293</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/e8abcd0e62b334c164b95d49fcabdc9ecbca0554"><code>e8abcd0</code></a>
Bump pypa/gh-action-pypi-publish from 1.8.14 to 1.9.0 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/292">#292</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/124f4adf171e15cd9a91a8b6e0325ecc97be8fe1"><code>124f4ad</code></a>
2024.06.02 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/291">#291</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/c2196ce5d6ee675b27755a19948480a7823e2c6a"><code>c2196ce</code></a>
--- (<a
href="https://redirect.github.com/certifi/python-certifi/issues/290">#290</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/fefdeec7588ff1c05214b85a552afcad5fdb51b2"><code>fefdeec</code></a>
Bump actions/checkout from 4.1.4 to 4.1.5 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/289">#289</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/3c5fb1560b826a7f83f1f9750173ff766492c9cf"><code>3c5fb15</code></a>
Bump actions/download-artifact from 4.1.6 to 4.1.7 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/286">#286</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/4a9569a3eb58db8548536fc16c5c5c7af946a5b1"><code>4a9569a</code></a>
Bump actions/checkout from 4.1.2 to 4.1.4 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/287">#287</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/1fc808626a895a916b1e4c2b63abae6c5eafdbe3"><code>1fc8086</code></a>
Bump peter-evans/create-pull-request from 6.0.4 to 6.0.5 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/288">#288</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/certifi/python-certifi/compare/2023.07.22...2024.07.04">compare
view</a></li>
</ul>
</details>
<br />

Updates `urllib3` from 2.0.7 to 2.2.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/urllib3/urllib3/releases">urllib3's
releases</a>.</em></p>
<blockquote>
<h2>2.2.2</h2>
<h2>🚀 urllib3 is fundraising for HTTP/2 support</h2>
<p><a
href="https://sethmlarson.dev/urllib3-is-fundraising-for-http2-support">urllib3
is raising ~$40,000 USD</a> to release HTTP/2 support and ensure
long-term sustainable maintenance of the project after a sharp decline
in financial support for 2023. If your company or organization uses
Python and would benefit from HTTP/2 support in Requests, pip, cloud
SDKs, and thousands of other projects <a
href="https://opencollective.com/urllib3">please consider contributing
financially</a> to ensure HTTP/2 support is developed sustainably and
maintained for the long-haul.</p>
<p>Thank you for your support.</p>
<h2>Changes</h2>
<ul>
<li>Added the <code>Proxy-Authorization</code> header to the list of
headers to strip from requests when redirecting to a different host. As
before, different headers can be set via
<code>Retry.remove_headers_on_redirect</code>.</li>
<li>Allowed passing negative integers as <code>amt</code> to read
methods of <code>http.client.HTTPResponse</code> as an alternative to
<code>None</code>. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3122">#3122</a>)</li>
<li>Fixed return types representing copying actions to use
<code>typing.Self</code>. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3363">#3363</a>)</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/urllib3/urllib3/compare/2.2.1...2.2.2">https://github.com/urllib3/urllib3/compare/2.2.1...2.2.2</a></p>
<h2>2.2.1</h2>
<h2>🚀 urllib3 is fundraising for HTTP/2 support</h2>
<p><a
href="https://sethmlarson.dev/urllib3-is-fundraising-for-http2-support">urllib3
is raising ~$40,000 USD</a> to release HTTP/2 support and ensure
long-term sustainable maintenance of the project after a sharp decline
in financial support for 2023. If your company or organization uses
Python and would benefit from HTTP/2 support in Requests, pip, cloud
SDKs, and thousands of other projects <a
href="https://opencollective.com/urllib3">please consider contributing
financially</a> to ensure HTTP/2 support is developed sustainably and
maintained for the long-haul.</p>
<p>Thank you for your support.</p>
<h2>Changes</h2>
<ul>
<li>Fixed issue where <code>InsecureRequestWarning</code> was emitted
for HTTPS connections when using Emscripten. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3331">#3331</a>)</li>
<li>Fixed <code>HTTPConnectionPool.urlopen</code> to stop automatically
casting non-proxy headers to <code>HTTPHeaderDict</code>. This change
was premature as it did not apply to proxy headers and
<code>HTTPHeaderDict</code> does not handle byte header values correctly
yet. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3343">#3343</a>)</li>
<li>Changed <code>ProtocolError</code> to
<code>InvalidChunkLength</code> when response terminates before the
chunk length is sent. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/2860">#2860</a>)</li>
<li>Changed <code>ProtocolError</code> to be more verbose on incomplete
reads with excess content. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3261">#3261</a>)</li>
</ul>
<h2>2.2.0</h2>
<h2>🖥️ urllib3 now works in the browser</h2>
<p>:tada: <strong>This release adds experimental support for <a
href="https://urllib3.readthedocs.io/en/stable/reference/contrib/emscripten.html">using
urllib3 in the browser with Pyodide</a>!</strong> 🎉</p>
<p>Thanks to Joe Marshall (<a
href="https://github.com/joemarshall"><code>@​joemarshall</code></a>)
for contributing this feature. This change was possible thanks to work
done in urllib3 v2.0 to detach our API from <code>http.client</code>.
Please report all bugs to the <a
href="https://github.com/urllib3/urllib3/issues">urllib3 issue
tracker</a>.</p>
<h2>🚀 urllib3 is fundraising for HTTP/2 support</h2>
<p><a
href="https://sethmlarson.dev/urllib3-is-fundraising-for-http2-support">urllib3
is raising ~$40,000 USD</a> to release HTTP/2 support and ensure
long-term sustainable maintenance of the project after a sharp decline
in financial support for 2023. If your company or organization uses
Python and would benefit from HTTP/2 support in Requests, pip, cloud
SDKs, and thousands of other projects <a
href="https://opencollective.com/urllib3">please consider contributing
financially</a> to ensure HTTP/2 support is developed sustainably and
maintained for the long-haul.</p>
<p>Thank you for your support.</p>
<h2>Changes</h2>
<ul>
<li>Added support for <a
href="https://urllib3.readthedocs.io/en/latest/reference/contrib/emscripten.html">Emscripten
and Pyodide</a>, including streaming support in cross-origin isolated
browser environments where threading is enabled. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/2951">#2951</a>)</li>
<li>Added support for <code>HTTPResponse.read1()</code> method. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3186">#3186</a>)</li>
<li>Added rudimentary support for HTTP/2. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3284">#3284</a>)</li>
<li>Fixed issue where requests against urls with trailing dots were
failing due to SSL errors
when using proxy. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/2244">#2244</a>)</li>
<li>Fixed <code>HTTPConnection.proxy_is_verified</code> and
<code>HTTPSConnection.proxy_is_verified</code> to be always set to a
boolean after connecting to a proxy. It could be <code>None</code> in
some cases previously. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3130">#3130</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/urllib3/urllib3/blob/main/CHANGES.rst">urllib3's
changelog</a>.</em></p>
<blockquote>
<h1>2.2.2 (2024-06-17)</h1>
<ul>
<li>Added the <code>Proxy-Authorization</code> header to the list of
headers to strip from requests when redirecting to a different host. As
before, different headers can be set via
<code>Retry.remove_headers_on_redirect</code>.</li>
<li>Allowed passing negative integers as <code>amt</code> to read
methods of <code>http.client.HTTPResponse</code> as an alternative to
<code>None</code>.
(<code>[#3122](urllib3/urllib3#3122)
&lt;https://github.com/urllib3/urllib3/issues/3122&gt;</code>__)</li>
<li>Fixed return types representing copying actions to use
<code>typing.Self</code>.
(<code>[#3363](urllib3/urllib3#3363)
&lt;https://github.com/urllib3/urllib3/issues/3363&gt;</code>__)</li>
</ul>
<h1>2.2.1 (2024-02-16)</h1>
<ul>
<li>Fixed issue where <code>InsecureRequestWarning</code> was emitted
for HTTPS connections when using Emscripten.
(<code>[#3331](urllib3/urllib3#3331)
&lt;https://github.com/urllib3/urllib3/issues/3331&gt;</code>__)</li>
<li>Fixed <code>HTTPConnectionPool.urlopen</code> to stop automatically
casting non-proxy headers to <code>HTTPHeaderDict</code>. This change
was premature as it did not apply to proxy headers and
<code>HTTPHeaderDict</code> does not handle byte header values correctly
yet. (<code>[#3343](urllib3/urllib3#3343)
&lt;https://github.com/urllib3/urllib3/issues/3343&gt;</code>__)</li>
<li>Changed <code>InvalidChunkLength</code> to
<code>ProtocolError</code> when response terminates before the chunk
length is sent.
(<code>[#2860](urllib3/urllib3#2860)
&lt;https://github.com/urllib3/urllib3/issues/2860&gt;</code>__)</li>
<li>Changed <code>ProtocolError</code> to be more verbose on incomplete
reads with excess content.
(<code>[#3261](urllib3/urllib3#3261)
&lt;https://github.com/urllib3/urllib3/issues/3261&gt;</code>__)</li>
</ul>
<h1>2.2.0 (2024-01-30)</h1>
<ul>
<li>Added support for <code>Emscripten and Pyodide
&lt;https://urllib3.readthedocs.io/en/latest/reference/contrib/emscripten.html&gt;</code><strong>,
including streaming support in cross-origin isolated browser
environments where threading is enabled.
(<code>[#2951](urllib3/urllib3#2951)
&lt;https://github.com/urllib3/urllib3/issues/2951&gt;</code></strong>)</li>
<li>Added support for <code>HTTPResponse.read1()</code> method.
(<code>[#3186](urllib3/urllib3#3186)
&lt;https://github.com/urllib3/urllib3/issues/3186&gt;</code>__)</li>
<li>Added rudimentary support for HTTP/2.
(<code>[#3284](urllib3/urllib3#3284)
&lt;https://github.com/urllib3/urllib3/issues/3284&gt;</code>__)</li>
<li>Fixed issue where requests against urls with trailing dots were
failing due to SSL errors
when using proxy.
(<code>[#2244](urllib3/urllib3#2244)
&lt;https://github.com/urllib3/urllib3/issues/2244&gt;</code>__)</li>
<li>Fixed <code>HTTPConnection.proxy_is_verified</code> and
<code>HTTPSConnection.proxy_is_verified</code>
to be always set to a boolean after connecting to a proxy. It could be
<code>None</code> in some cases previously.
(<code>[#3130](urllib3/urllib3#3130)
&lt;https://github.com/urllib3/urllib3/issues/3130&gt;</code>__)</li>
<li>Fixed an issue where <code>headers</code> passed in a request with
<code>json=</code> would be mutated
(<code>[#3203](urllib3/urllib3#3203)
&lt;https://github.com/urllib3/urllib3/issues/3203&gt;</code>__)</li>
<li>Fixed <code>HTTPSConnection.is_verified</code> to be set to
<code>False</code> when connecting
from a HTTPS proxy to an HTTP target. It was set to <code>True</code>
previously.
(<code>[#3267](urllib3/urllib3#3267)
&lt;https://github.com/urllib3/urllib3/issues/3267&gt;</code>__)</li>
<li>Fixed handling of new error message from OpenSSL 3.2.0 when
configuring an HTTP proxy as HTTPS
(<code>[#3268](urllib3/urllib3#3268)
&lt;https://github.com/urllib3/urllib3/issues/3268&gt;</code>__)</li>
<li>Fixed TLS 1.3 post-handshake auth when the server certificate
validation is disabled
(<code>[#3325](urllib3/urllib3#3325)
&lt;https://github.com/urllib3/urllib3/issues/3325&gt;</code>__)</li>
<li>Note for downstream distributors: To run integration tests, you now
need to run the tests a second
time with the <code>--integration</code> pytest flag.
(<code>[#3181](urllib3/urllib3#3181)
&lt;https://github.com/urllib3/urllib3/issues/3181&gt;</code>__)</li>
</ul>
<h1>2.1.0 (2023-11-13)</h1>
<ul>
<li>Removed support for the deprecated urllib3[secure] extra.
(<code>[#2680](urllib3/urllib3#2680)
&lt;https://github.com/urllib3/urllib3/issues/2680&gt;</code>__)</li>
<li>Removed support for the deprecated SecureTransport TLS
implementation.
(<code>[#2681](urllib3/urllib3#2681)
&lt;https://github.com/urllib3/urllib3/issues/2681&gt;</code>__)</li>
<li>Removed support for the end-of-life Python 3.7.
(<code>[#3143](urllib3/urllib3#3143)
&lt;https://github.com/urllib3/urllib3/issues/3143&gt;</code>__)</li>
<li>Allowed loading CA certificates from memory for proxies.
(<code>[#3065](urllib3/urllib3#3065)
&lt;https://github.com/urllib3/urllib3/issues/3065&gt;</code>__)</li>
<li>Fixed decoding Gzip-encoded responses which specified
<code>x-gzip</code> content-encoding.
(<code>[#3174](urllib3/urllib3#3174)
&lt;https://github.com/urllib3/urllib3/issues/3174&gt;</code>__)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/urllib3/urllib3/commit/27e2a5c5a7ab6a517252cc8dcef3ffa6ffb8f61a"><code>27e2a5c</code></a>
Release 2.2.2 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3406">#3406</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/accff72ecc2f6cf5a76d9570198a93ac7c90270e"><code>accff72</code></a>
Merge pull request from GHSA-34jh-p97f-mpxf</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/34be4a57e59eb7365bcc37d52e9f8271b5b8d0d3"><code>34be4a5</code></a>
Pin CFFI to a new release candidate instead of a Git commit (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3398">#3398</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/da410581b6b3df73da976b5ce5eb20a4bd030437"><code>da41058</code></a>
Bump browser-actions/setup-chrome from 1.6.0 to 1.7.1 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3399">#3399</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/b07a669bd970d69847801148286b726f0570b625"><code>b07a669</code></a>
Bump github/codeql-action from 2.13.4 to 3.25.6 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3396">#3396</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/b8589ec9f8c4da91511e601b632ac06af7e7c10e"><code>b8589ec</code></a>
Measure coverage with v4 of artifact actions (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3394">#3394</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/f3bdc5585111429e22c81b5fb26c3ec164d98b81"><code>f3bdc55</code></a>
Allow triggering CI manually (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3391">#3391</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/52392654b30183129cf3ec06010306f517d9c146"><code>5239265</code></a>
Fix HTTP version in debug log (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3316">#3316</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/b34619f94ece0c40e691a5aaf1304953d88089de"><code>b34619f</code></a>
Bump actions/checkout to 4.1.4 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3387">#3387</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/9961d14de7c920091d42d42ed76d5d479b80064d"><code>9961d14</code></a>
Bump browser-actions/setup-chrome from 1.5.0 to 1.6.0 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3386">#3386</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/urllib3/urllib3/compare/2.0.7...2.2.2">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/envoyproxy/envoy/network/alerts).

</details>

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
phlax pushed a commit that referenced this pull request Jul 15, 2024
…e/client in the pip group (#34784)

Bumps the pip group in /examples/grpc-bridge/client with 1 update:
[urllib3](https://github.com/urllib3/urllib3).

Updates `urllib3` from 2.0.7 to 2.2.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/urllib3/urllib3/releases">urllib3's
releases</a>.</em></p>
<blockquote>
<h2>2.2.2</h2>
<h2>🚀 urllib3 is fundraising for HTTP/2 support</h2>
<p><a
href="https://sethmlarson.dev/urllib3-is-fundraising-for-http2-support">urllib3
is raising ~$40,000 USD</a> to release HTTP/2 support and ensure
long-term sustainable maintenance of the project after a sharp decline
in financial support for 2023. If your company or organization uses
Python and would benefit from HTTP/2 support in Requests, pip, cloud
SDKs, and thousands of other projects <a
href="https://opencollective.com/urllib3">please consider contributing
financially</a> to ensure HTTP/2 support is developed sustainably and
maintained for the long-haul.</p>
<p>Thank you for your support.</p>
<h2>Changes</h2>
<ul>
<li>Added the <code>Proxy-Authorization</code> header to the list of
headers to strip from requests when redirecting to a different host. As
before, different headers can be set via
<code>Retry.remove_headers_on_redirect</code>.</li>
<li>Allowed passing negative integers as <code>amt</code> to read
methods of <code>http.client.HTTPResponse</code> as an alternative to
<code>None</code>. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3122">#3122</a>)</li>
<li>Fixed return types representing copying actions to use
<code>typing.Self</code>. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3363">#3363</a>)</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/urllib3/urllib3/compare/2.2.1...2.2.2">https://github.com/urllib3/urllib3/compare/2.2.1...2.2.2</a></p>
<h2>2.2.1</h2>
<h2>🚀 urllib3 is fundraising for HTTP/2 support</h2>
<p><a
href="https://sethmlarson.dev/urllib3-is-fundraising-for-http2-support">urllib3
is raising ~$40,000 USD</a> to release HTTP/2 support and ensure
long-term sustainable maintenance of the project after a sharp decline
in financial support for 2023. If your company or organization uses
Python and would benefit from HTTP/2 support in Requests, pip, cloud
SDKs, and thousands of other projects <a
href="https://opencollective.com/urllib3">please consider contributing
financially</a> to ensure HTTP/2 support is developed sustainably and
maintained for the long-haul.</p>
<p>Thank you for your support.</p>
<h2>Changes</h2>
<ul>
<li>Fixed issue where <code>InsecureRequestWarning</code> was emitted
for HTTPS connections when using Emscripten. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3331">#3331</a>)</li>
<li>Fixed <code>HTTPConnectionPool.urlopen</code> to stop automatically
casting non-proxy headers to <code>HTTPHeaderDict</code>. This change
was premature as it did not apply to proxy headers and
<code>HTTPHeaderDict</code> does not handle byte header values correctly
yet. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3343">#3343</a>)</li>
<li>Changed <code>ProtocolError</code> to
<code>InvalidChunkLength</code> when response terminates before the
chunk length is sent. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/2860">#2860</a>)</li>
<li>Changed <code>ProtocolError</code> to be more verbose on incomplete
reads with excess content. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3261">#3261</a>)</li>
</ul>
<h2>2.2.0</h2>
<h2>🖥️ urllib3 now works in the browser</h2>
<p>:tada: <strong>This release adds experimental support for <a
href="https://urllib3.readthedocs.io/en/stable/reference/contrib/emscripten.html">using
urllib3 in the browser with Pyodide</a>!</strong> 🎉</p>
<p>Thanks to Joe Marshall (<a
href="https://github.com/joemarshall"><code>@​joemarshall</code></a>)
for contributing this feature. This change was possible thanks to work
done in urllib3 v2.0 to detach our API from <code>http.client</code>.
Please report all bugs to the <a
href="https://github.com/urllib3/urllib3/issues">urllib3 issue
tracker</a>.</p>
<h2>🚀 urllib3 is fundraising for HTTP/2 support</h2>
<p><a
href="https://sethmlarson.dev/urllib3-is-fundraising-for-http2-support">urllib3
is raising ~$40,000 USD</a> to release HTTP/2 support and ensure
long-term sustainable maintenance of the project after a sharp decline
in financial support for 2023. If your company or organization uses
Python and would benefit from HTTP/2 support in Requests, pip, cloud
SDKs, and thousands of other projects <a
href="https://opencollective.com/urllib3">please consider contributing
financially</a> to ensure HTTP/2 support is developed sustainably and
maintained for the long-haul.</p>
<p>Thank you for your support.</p>
<h2>Changes</h2>
<ul>
<li>Added support for <a
href="https://urllib3.readthedocs.io/en/latest/reference/contrib/emscripten.html">Emscripten
and Pyodide</a>, including streaming support in cross-origin isolated
browser environments where threading is enabled. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/2951">#2951</a>)</li>
<li>Added support for <code>HTTPResponse.read1()</code> method. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3186">#3186</a>)</li>
<li>Added rudimentary support for HTTP/2. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3284">#3284</a>)</li>
<li>Fixed issue where requests against urls with trailing dots were
failing due to SSL errors
when using proxy. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/2244">#2244</a>)</li>
<li>Fixed <code>HTTPConnection.proxy_is_verified</code> and
<code>HTTPSConnection.proxy_is_verified</code> to be always set to a
boolean after connecting to a proxy. It could be <code>None</code> in
some cases previously. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3130">#3130</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/urllib3/urllib3/blob/main/CHANGES.rst">urllib3's
changelog</a>.</em></p>
<blockquote>
<h1>2.2.2 (2024-06-17)</h1>
<ul>
<li>Added the <code>Proxy-Authorization</code> header to the list of
headers to strip from requests when redirecting to a different host. As
before, different headers can be set via
<code>Retry.remove_headers_on_redirect</code>.</li>
<li>Allowed passing negative integers as <code>amt</code> to read
methods of <code>http.client.HTTPResponse</code> as an alternative to
<code>None</code>.
(<code>[#3122](urllib3/urllib3#3122)
&lt;https://github.com/urllib3/urllib3/issues/3122&gt;</code>__)</li>
<li>Fixed return types representing copying actions to use
<code>typing.Self</code>.
(<code>[#3363](urllib3/urllib3#3363)
&lt;https://github.com/urllib3/urllib3/issues/3363&gt;</code>__)</li>
</ul>
<h1>2.2.1 (2024-02-16)</h1>
<ul>
<li>Fixed issue where <code>InsecureRequestWarning</code> was emitted
for HTTPS connections when using Emscripten.
(<code>[#3331](urllib3/urllib3#3331)
&lt;https://github.com/urllib3/urllib3/issues/3331&gt;</code>__)</li>
<li>Fixed <code>HTTPConnectionPool.urlopen</code> to stop automatically
casting non-proxy headers to <code>HTTPHeaderDict</code>. This change
was premature as it did not apply to proxy headers and
<code>HTTPHeaderDict</code> does not handle byte header values correctly
yet. (<code>[#3343](urllib3/urllib3#3343)
&lt;https://github.com/urllib3/urllib3/issues/3343&gt;</code>__)</li>
<li>Changed <code>InvalidChunkLength</code> to
<code>ProtocolError</code> when response terminates before the chunk
length is sent.
(<code>[#2860](urllib3/urllib3#2860)
&lt;https://github.com/urllib3/urllib3/issues/2860&gt;</code>__)</li>
<li>Changed <code>ProtocolError</code> to be more verbose on incomplete
reads with excess content.
(<code>[#3261](urllib3/urllib3#3261)
&lt;https://github.com/urllib3/urllib3/issues/3261&gt;</code>__)</li>
</ul>
<h1>2.2.0 (2024-01-30)</h1>
<ul>
<li>Added support for <code>Emscripten and Pyodide
&lt;https://urllib3.readthedocs.io/en/latest/reference/contrib/emscripten.html&gt;</code><strong>,
including streaming support in cross-origin isolated browser
environments where threading is enabled.
(<code>[#2951](urllib3/urllib3#2951)
&lt;https://github.com/urllib3/urllib3/issues/2951&gt;</code></strong>)</li>
<li>Added support for <code>HTTPResponse.read1()</code> method.
(<code>[#3186](urllib3/urllib3#3186)
&lt;https://github.com/urllib3/urllib3/issues/3186&gt;</code>__)</li>
<li>Added rudimentary support for HTTP/2.
(<code>[#3284](urllib3/urllib3#3284)
&lt;https://github.com/urllib3/urllib3/issues/3284&gt;</code>__)</li>
<li>Fixed issue where requests against urls with trailing dots were
failing due to SSL errors
when using proxy.
(<code>[#2244](urllib3/urllib3#2244)
&lt;https://github.com/urllib3/urllib3/issues/2244&gt;</code>__)</li>
<li>Fixed <code>HTTPConnection.proxy_is_verified</code> and
<code>HTTPSConnection.proxy_is_verified</code>
to be always set to a boolean after connecting to a proxy. It could be
<code>None</code> in some cases previously.
(<code>[#3130](urllib3/urllib3#3130)
&lt;https://github.com/urllib3/urllib3/issues/3130&gt;</code>__)</li>
<li>Fixed an issue where <code>headers</code> passed in a request with
<code>json=</code> would be mutated
(<code>[#3203](urllib3/urllib3#3203)
&lt;https://github.com/urllib3/urllib3/issues/3203&gt;</code>__)</li>
<li>Fixed <code>HTTPSConnection.is_verified</code> to be set to
<code>False</code> when connecting
from a HTTPS proxy to an HTTP target. It was set to <code>True</code>
previously.
(<code>[#3267](urllib3/urllib3#3267)
&lt;https://github.com/urllib3/urllib3/issues/3267&gt;</code>__)</li>
<li>Fixed handling of new error message from OpenSSL 3.2.0 when
configuring an HTTP proxy as HTTPS
(<code>[#3268](urllib3/urllib3#3268)
&lt;https://github.com/urllib3/urllib3/issues/3268&gt;</code>__)</li>
<li>Fixed TLS 1.3 post-handshake auth when the server certificate
validation is disabled
(<code>[#3325](urllib3/urllib3#3325)
&lt;https://github.com/urllib3/urllib3/issues/3325&gt;</code>__)</li>
<li>Note for downstream distributors: To run integration tests, you now
need to run the tests a second
time with the <code>--integration</code> pytest flag.
(<code>[#3181](urllib3/urllib3#3181)
&lt;https://github.com/urllib3/urllib3/issues/3181&gt;</code>__)</li>
</ul>
<h1>2.1.0 (2023-11-13)</h1>
<ul>
<li>Removed support for the deprecated urllib3[secure] extra.
(<code>[#2680](urllib3/urllib3#2680)
&lt;https://github.com/urllib3/urllib3/issues/2680&gt;</code>__)</li>
<li>Removed support for the deprecated SecureTransport TLS
implementation.
(<code>[#2681](urllib3/urllib3#2681)
&lt;https://github.com/urllib3/urllib3/issues/2681&gt;</code>__)</li>
<li>Removed support for the end-of-life Python 3.7.
(<code>[#3143](urllib3/urllib3#3143)
&lt;https://github.com/urllib3/urllib3/issues/3143&gt;</code>__)</li>
<li>Allowed loading CA certificates from memory for proxies.
(<code>[#3065](urllib3/urllib3#3065)
&lt;https://github.com/urllib3/urllib3/issues/3065&gt;</code>__)</li>
<li>Fixed decoding Gzip-encoded responses which specified
<code>x-gzip</code> content-encoding.
(<code>[#3174](urllib3/urllib3#3174)
&lt;https://github.com/urllib3/urllib3/issues/3174&gt;</code>__)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/urllib3/urllib3/commit/27e2a5c5a7ab6a517252cc8dcef3ffa6ffb8f61a"><code>27e2a5c</code></a>
Release 2.2.2 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3406">#3406</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/accff72ecc2f6cf5a76d9570198a93ac7c90270e"><code>accff72</code></a>
Merge pull request from GHSA-34jh-p97f-mpxf</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/34be4a57e59eb7365bcc37d52e9f8271b5b8d0d3"><code>34be4a5</code></a>
Pin CFFI to a new release candidate instead of a Git commit (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3398">#3398</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/da410581b6b3df73da976b5ce5eb20a4bd030437"><code>da41058</code></a>
Bump browser-actions/setup-chrome from 1.6.0 to 1.7.1 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3399">#3399</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/b07a669bd970d69847801148286b726f0570b625"><code>b07a669</code></a>
Bump github/codeql-action from 2.13.4 to 3.25.6 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3396">#3396</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/b8589ec9f8c4da91511e601b632ac06af7e7c10e"><code>b8589ec</code></a>
Measure coverage with v4 of artifact actions (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3394">#3394</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/f3bdc5585111429e22c81b5fb26c3ec164d98b81"><code>f3bdc55</code></a>
Allow triggering CI manually (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3391">#3391</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/52392654b30183129cf3ec06010306f517d9c146"><code>5239265</code></a>
Fix HTTP version in debug log (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3316">#3316</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/b34619f94ece0c40e691a5aaf1304953d88089de"><code>b34619f</code></a>
Bump actions/checkout to 4.1.4 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3387">#3387</a>)</li>
<li><a
href="https://github.com/urllib3/urllib3/commit/9961d14de7c920091d42d42ed76d5d479b80064d"><code>9961d14</code></a>
Bump browser-actions/setup-chrome from 1.5.0 to 1.6.0 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3386">#3386</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/urllib3/urllib3/compare/2.0.7...2.2.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=urllib3&package-manager=pip&previous-version=2.0.7&new-version=2.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/envoyproxy/envoy/network/alerts).

</details>

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants