Re-Rebalancing Coherence

RFC #1023 introduced rules that exclude impls which should clearly be
valid. It also used some ambiguous language around what is a breaking
change, that ended up being completely ignored and contradicted by #1105.
This RFC seeks to clarify what is or isn't a breaking change when it
comes to implementing an existing trait, and conservatively expands the
orphan rules to allow impls which do not violate coherence, and fit
within the original goals of #1023.
Rendered

Honestly, this RFC is the clearest explanation of the coherence rules I've seen to date - the proposed rules actually seem simpler to understand with less special casing.
Is it necessarily true that all blanket impls are a breaking change? At the very least, new traits can obviously have blanket impls backwards compatibly, but even for existing traits, aren't there any cases where a blanket impl can be safely added?
I hope in the long term there will be some way for the author of the type/trait to customize the coherence rules (like a more advanced version of the #[fundamental] attribute) rather than having to work around them.

Honestly, this RFC is the clearest explanation of the coherence rules I've seen to date - the proposed rules actually seem simpler to understand with less special casing.

 Now that I'm looking at it, the formal definition in #1023 is just incomplete and ambiguous (although I assume it was intended to mean something similar to what this new RFC proposes).

Is it necessarily true that all blanket impls are a breaking change? At the very least, new traits can obviously have blanket impls backwards compatibly, but even for existing traits, aren't there any cases where a blanket impl can be safely added?

With the set of impls that are accepted today, there is no case where a blanket impl can be added for an existing trait with an existing type. impl<T> SomeTrait<T> for NewType is of course completely valid, since nothing could be depending on NewType yet. While the wording is vague, this is the original intent behind #1023.

I hope in the long term there will be some way for the author of the type/trait to customize the coherence rules

I agree, and I think many others do as well. However, any substantial change to coherence in that direction will require much more work, will almost certainly be completely blocked on chalk, and need to be tied to an edition. My goal with this RFC was for something more conservative that is able to land more quickly, regardless of whether or not we want to develop a more comprehensive solution in the future.

awesome write up.
however minor nitpick, your use of double negatives was a little confusing in
the phrase below

Target is not an uncovered type parameter (is not any of P1...Pn)

I think you should simplify it to

Target is a covered type parameter(is not any of P1...Pn)

Is it necessarily true that all blanket impls are a breaking change? At the very least, new traits can obviously have blanket impls backwards compatibly, but even for existing traits, aren't there any cases where a blanket impl can be safely added?

Have we given up on specialization? If the new blanket impl is a default impl it can always be added backwards compatibly, right?

In digest crate I have traits which describe functionality of cryptographic hash functions. One of the traits is:
pub trait Input {
    fn process(&mut self, input: &[u8]);
}

And ideally I would like to write blank impl for io::Write:
impl<T: Input> io::Write for T {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { .. }
}

But obviously it can not be done under current coherence rules, thus I have to implement io::Write for all hash functions manually. If I understand correctly this RFC still disallows such implementations. I think a good approach to this particular problem will be "negative trait bounds", which have been proposed several times, but seems without any results. They will allow me to write the code like this:
// `!io::Write` bound means that other crates can't implement
// both `Input` and `io::Write` on the same time
pub trait Input: !io::Write {
    fn process(&mut self, input: &[u8]);
}

// But locally we can define blank impl of `io::Write`, because compiler
// guarantees that no one else can implement it for `T: Input`
impl<T: Input> io::Write for T {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { .. }
}

@newpavlov Why can't you have something like this:
pub struct InputWriter<T>(T);

impl<T: Input> Write for InputWriter<T> {}

@abonander
Because io::copy(&mut my_file, InputWriter::new(&mut hasher)) is less convenient and harder to explain/discover than io::copy(&mut my_file, &mut hasher). Plus negative trait bounds have various applications. Also see motivation for #1148 .

Covered Type: A type which appears as a parameter to another type. For example, T is uncovered, but Vec<T> is covered. This is only relevant for type parameters.

Is (T,) considered covered or uncovered? I think it should be covered, but don't think the current definition covers it. This would have implications about allowing for example impl<T, U> ForeignTrait<LocalType> for (T, U).

@tspiteri (T,) is covered

(T,) is covered

@sgrif Are you sure? Tuples are fundamental, iirc

@leodasvacas Tuples are definitely not fundamental

Sorry I've been slow to leave comments here. I am basically 👍 on this RFC. I had a few nitpicks on the phrasing, though I think others have mostly left similar comments; I'll have to go over my notes later.

I did also have one particular question: I feel like the rules as stated in the RFC are unnecessarily narrow. The RFC states:

Given impl<P1...Pn> Trait<T1...Tn> for Target, an impl is valid only if at
least one of the following is true:

Trait is a local trait
Target is a local type
All of

Target is not an uncovered type parameter (is not any of P1...Pn)
At least one of the types T1...Tn must be a local type. Let Ti be the
first such type.
No type parameters P1...Pn may appear anywhere in T1...Tn before Ti.

It surprised me to see the Target type drawn out specially... I suspect we can make a more general change. For example, this change permits
impl ForeignTrait1<LocalType> for ForeignType<T>

but it forbids
impl ForeignTrait2<ForeignType<T>, LocalType> for u32

Granted, the number of traits that include enough type parameters to make this relevant are few.
Nonetheless, I think I would prefer to see the final rule without calling out Target specifically. Something like this:

Given impl<P0...Pn> Trait<T1...Tn> for T0, an impl is valid only if at
least one of the following is true:

Trait is a local trait
All of

At least one of the types T0..=Tn must be a local type. Let Ti be the
first such type.
No type parameters P0..=Pn appear uncovered in T0..Ti (excluding Ti).

The major change from today being that we do not forbid type parameters "deeply" from T0..Ti, but rather just forbid uncovered type parameters.
Is there a reason we can't do this? It seems clear that this creates no more conflict with parent crates than existed before: for them to overlap with us, they must use an uncovered type parameter at position Ti, and (as you correctly observe).
In terms of sibling or cousin crates, I think the argument is similar. Assume there are two cousin crates (neither is a (transitive) dependency of the other) with impls of the same trait Trait:

Let i and j be the positions where each crate has its local type

since Trait is used by both crates, it cannot be located in either crate, as they are not dependencies of one another

If i == j, then these two types clearly cannot equate, as they are local to different crates.
Otherwise, let i be the lower index, and let us say it is in crate A and call the other crate B

Then crate B must have a "remote type" at position i (e.g., Vec<T> and so forth)
This cannot equate with the local type in crate A

Is there a flaw in this reasoning?
I guess the question is why we used the "no type parameters at all" rule in the first place. I think this has to do with historical context. It's worth remembering that these rules arose before RFC 1023 ("rebalancing coherence"), and in that setting we didn't have a notion of fundamental types. I remember that we were concerned about the symmetry of impl<T> Foo<T> for A and impl<T> Foo for (A, T). In particular, we wanted to accept something like (Vec<T>, T) but reject (Foo, T), because T was "uncovered" in the latter. Because tuples are not fundamental, this no longer seems to be an issue.

More generally, @Sunjay and I have been working over in Chalk land on modeling the coherence rules and I think we're starting to make some nice progress. This work dovetails pretty nicely with this RFC. To keep this comment from getting too crazy long I'll hold off on commenting too much about it here. Maybe they can write more, or maybe I'll drop some tidbits later. The two main things we've been focused on are separating out the "axioms" (i.e., the things we define by fiat) -- from the "theorems" (i.e., the things we believe follow from that), as well as trying to state the rules in terms of chalk predicates. For example, there is a predicate IsUpstream(T) which states if a type is known to be "owned" by an upstream crate and so forth. I believe  this version

@nikomatsakis: Um, did you mean to finish this sentence with something other than "and"? Your comment was really interesting to read otherwise...

they must use an uncovered type parameter at position Ti, and (as you correctly observe).

Changed to:

Is there a reason we can't do this? It seems clear that this creates no more conflict with parent crates than existed before: for them to overlap with us, they must use an uncovered type parameter at position Ti (which you correctly observe would be a semver violation to add, despite some confusing wording elsewhere). (Update: fixed this paragraph, which previously ended mid-sentence.)

An impl of
impl<T> ForeignTrait<LocalType> for ForeignType<T>

Requires that cousin crates are not able to write the following impl
impl<T> ForeignTrait<T> for ForeignType<CousinLocalType>

If ForeignType is #[fundamental] (for example, consider the case where ForeignType = Box), then, by the current rules, the cousin impl is legal, which means the "original" impl must not be.
If ForeignType is not #[fundamental], the current rules forbid the cousin impl, but they don't take it being forbidden into account - i.e. adding #[fundamental] to a type is not a breaking change, while with this RFC, it must be.

So, taking fundamental types into account, the "new" rules could be:
The predicate we want to define is "trait-ref R is orphan-owned by crate C". We split types into 3 categories:

Types local to C - types that are defined in C
Non-local types known to C - types that are defined in parents of C
Types not known to C - types from sibling crates

The rules are:

An impl for a trait local in C is always orphan-owned by C.
Otherwise, a trait-ref T_0: Foo<T_1, T_2...> (note that T_0 comes before T_1, T_2...) for a trait is orphan-owned by C if there's a local key parameter T_i such that:
2.a. T_i contains a local type behind an unbroken sequence of #[fundamental] types (which "implicitly" must be known to this crate).
2.b. For all parameters T_j where j <= i, for every instance of a type not known to C, that instance is behind an unbroken sequence of #[fundamental] types, followed by either a local type or a non-#[fundamental] known type. The non-#[fundamental] known type part is new.

Connections
An impl impl<T0, T1> Foo<T1> for T0 is orphan-legal in crate C iff for every instantiation of T0/T1, the resulting trait-ref is orphan-owned by C.
Coherence can perform negative reasoning on a trait-ref R if either:

R comes from a #[fundamental] trait, and no unknown crate can own R.
R comes from a non-#[fundamental] trait, and this crate owns R.

This is exactly the future-compatibility rules - adding an impl to a trait is future-compatible if that trait is non-#[fundamental], and no other crate can orphan-own any instantiation of that impl.
Unbroken rules
The "unbroken sequence of #[fundamental] types" part in 2.b. isn't strictly necessary for soundness - it basically says whether we allow this impl:
impl<T> RemoteTrait for FundamentalPair<LocalType<T>, Vec<LocalType<T>>>

However, negative reasoning depends on the orphan rules, so any change in the orphan rules is a breaking change.
Soundness proof
To show that this is sound, suppose that there is a trait-ref R and 2 cousin crates C1 and C2 that impl it. This means R is orphan-owned by both C1 and C2.
Suppose T_i is the key parameter in C1, T_j is the key parameter in C2. WLOG j <= i. By 2.a., T_j contains a C2-local type behind a sequence of #[fundamental] types known to C2.
However, these types can't be local in C1 (because C1 and C2 are cousin crates), and the C2-local type is not known in C1, that type can't be behind either a local type or a non-#[fundamental] known type,

Just so folks know, I'm on vacation but will reply in a few days

I'm sorry it's taken me so long to respond.
@nikomatsakis I agree with you, I see no reason we can't permit everything you've proposed. I feel like there was a specific reason that the covered rule wasn't sufficient here in the past, and I'd probably want to give some of the write-ups from that era another read before updating the RFC, but I think you're right.
@arielb1

An impl of
impl ForeignTrait for ForeignType
Requires that cousin crates are not able to write the following impl
impl ForeignTrait for ForeignType

The second impl is forbidden today, and continues to be forbidden under this RFC. You must have a local type appear before an uncovered type parameter. The types that appear in your impl are [ForeignType<CousinLocalType>, T] none of which are local to any crate except for the crate which defines ForeignType.
Taking fundamental types into account here actually doesn't matter for your point. Adding an impl like this where the type parameter T appears uncovered is a blanket impl, which is a breaking change, as defined in #1023.

I'll have to re-read your second comment a few times before I can respond

@sgrif

The second impl is forbidden today, and continues to be forbidden under this RFC.

If ForeignType is #[fundamental], it is definitely allowed, as CousinLocalType is local in the crate that defines it.
For example, this compiles today in a crate that defines neither Box nor Add:
use std::ops::Add;

type ForeignType<T> = Box<T>;

struct CousinLocalType;

impl<T> Add<T> for ForeignType<CousinLocalType> {
    type Output = ();
    fn add(self, rhs: T) {}
}

fn main() {}

The above example would require us to prevent impls of Add<LocalType> for Box<T>.

@arielb1 Yes, and this RFC does. I've explicitly called out fundamental types early on, and stated that for the purposes of coherence any fundamental type wrapping T is treated the same as T. So your impl is rejected because it would be rejected without the Box.

https://github.com/rust-lang/rfcs/pull/2451/files#diff-c4a0a5436b92a5fea6cfa7c0367e8cb7R79 is the relevant paragraph. I could probably make it clearer what the implications of treating T as non-covered in this case are

@sgrif
So I think we agree on which impls are allowed. I just wanted to have a complete-r spec of things so that we can spot problems in it more easily.

Understood

@rfcbot fcp merge
Overall I think this RFC is clear and well-written, and that the extension it proposes is logical -- though (as I noted earlier) [we could go a bit further]. I'm moving to merge this proposal, therefore, so as to get the ball rolling.

@rfcbot concern we-can-do-better
I'd like to see the extension described in this comment.

@rfcbot concern clarify-semver-implications
As noted here, some of the existing text could be clarified to show that it rejects @arielb1'1 impl.

Adding any impl with an uncovered type parameter is considered a major breaking change.

Without knowing the details, an impl like MyTrait<T> for MyType doesn't look like a breaking change to me in the same way that MyTrait<MyType> for T does. This is solely because of our syntax, of course: you have to be pretty advanced to understand the symmetry between the self type and the other parameters to a trait.
However, the argument could be made (and is to an extent in the RFC) that we've already crossed this bridge by making MyTrait<T> for MyType<T> a breaking change, and so this is just a simplification of the rule for what we consider a "breaking impl."
Not sure how to feel about this. :-\

@withoutboats For the record, that is a clarification of what was the intent of #1023. The wording could have been clearer, but @nikomatsakis has confirmed that is what "blanket impl" was intended to mean

Traditionally, we've observed a sort of "power imbalance" between upstream and downstream crates. In particular, an upstream crate must be conservative with what it adds, because it cannot control what sorts of impls downstream crates may create -- anything that they can legally make, the upstream crate must assume that they have done so.
From this POV, and barring any add'l mechanism, adding a impl MyTrait<T> for MyType simply is a breaking change -- it may cause downstream crates not to compile.
Nonetheless, @withoutboats, I shared your concern -- but I don't think that this RFC is to blame for that situation. It's just describing the world as it is.
If we want to make it possible to add an impl like impl MyTrait<T> for MyType later, then I think we need to make some sort of new mechanism to prevent conflicts with downstream crates. For example, you might imagine allowing traits to declare "roles" for their type parameters, or opt into distinct rules. This is what we were hoping to avoid initially, but I'm not really sure if it's possible to do so. It seems like something that warrants study -- e.g., surveying of use cases and so forth.
(We could of course just say that -- even though they can -- downstream impls ought not to add something like impl Foo<MyType> for u32 for a remote trait Foo, because they are not permitted to. This strikes me as a backwards incompatible change, though.)

Just a note, as a new, non-library rust developer, I'm tripping hard over the orphan rules when I'm attempting to export other crates's objects to a scripting language like gluon.
Right now, until I figure out the 'trick' (I've been trying the pattern with GluonUser without success), it seems vastly harder than it should be in that context. I've got to believe it's problematic for other cases.
This RFC doesn't appear to take into account such concerns. I guess I would like an option to just ignore the orphan rules - even in stable - even if it comes with the caveat 'do this at your own peril'.

@jrpascucci The alternative of "do this at your own peril" is not "allow anything", but rather "allow writing the impl but check it later" (checking for overlap between dependencies of each crate).

@eddyb Ostensibly, there could be overlappable trait (i.e. #[marker] trait but on steroids) which does not have the coherence property (and so unsafe code may not assume it as an invariant); but it seems unlikely that we'd do that.

@Centril coherence has nothing to do with unsafe code, and everything to do with soundness, i.e. you can break type safety from safe code with incoherent impls.
If we don't check coherence "late" (between dependencies of a downstream crate), we'd have to re-type-check everything at monomorphization time, to ensure nothing has changed from how it was observed at the definition site, and I'm not sure this is a tractable problem at all (it's similar to unsoundness caused by non-deterministic const eval: you must log everything you do, and recheck/reuse it later).

Maybe someone has suggested it, but how about if
type LocalType = ;
could safely allow locally defined foreign impls to override the original?
That seems to allow for inter-crate coherence, doesn't it?
So
type SafeCleartext = String;
with
impl<'a> From<&'a str> for SafeCleartext ...
, I presently get:
note: conflicting implementation in crate alloc:
- impl<'a> std::convert::From<&'a str> for std::string::String;

That doesn't solve anything because type aliases are transparent (not type
safe). When a function takes a parameter of type SafeCleartext you can
still pass a String, and vice versa.
On Thu, Sep 13, 2018 at 3:09 PM J. R. Pascucci<EMAIL_ADDRESS>wrote:

Maybe someone has suggested it, but how about if
type LocalType = ;
could safely allow locally defined foreign impls to override the original?
That seems to allow for inter-crate coherence, doesn't it?
So
type SafeCleartext = String;
with
impl<'a> From<&'a str> for SafeCleartext ...
, I presently get:
note: conflicting implementation in crate alloc:

impl<'a> std::convert::From<&'a str> for std::string::String;

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rfcs/pull/2451#issuecomment-421118657, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAC3n5stva3SIpEn6Kkc-h3YhzzxC_SHks5uaq2DgaJpZM4UT83X
.

What about some way to add "external features" to a crate. For example, if you are using a crate foo and want to add serde impls you could do
[dependencies.foo.external_features]
foo_serde = "0.1.0"

The idea being that the code from foo_serde is checked for coherence as if it were part of foo.
The main issue I can see is that if foo decides to add serde impls themselves, downstream crates using foo_serde will break, even though AFAIK adding trait impls is not currently considered a breaking change?

I've updated this RFC to address the concerns. The rules now match what @nikomatsakis proposed, allowing the impls mentioned in https://github.com/rust-lang/rfcs/pull/2451/files#issuecomment-399406030. I've also given an additional callout to how fundamental types are treated, which should clarify the concerns in https://github.com/rust-lang/rfcs/pull/2451#issuecomment-410383154
This should be good for FCP, I'd love if it this can get nominated for the next lang meeting

@sgrif I've nominated it for discussion on the meeting; but it is unlikely that we'll get to discuss it during the meeting since all edition related matters get priority in the queue.

Covered Type: A type which appears as a parameter to another type. For example, T is uncovered, but Vec<T> is covered. This is only relevant for type parameters.

Shouldn't "Vec<T> is covered" be: "T in Vec<T> is covered"? Also, what is the last sentence clarifying? "This is only relevant for type parameters" as opposed to what? Trait bounds? Additionally, while possibly stating the obvious, it would be nice to remind within the same paragraph that a trait doesn't cover its type parameter: impl<T> Bar<T> for Vec<T>. This is stated as an example in the blanket impl paragraph, but I got initially a bit confused about the covered definition in its current form so any clarification would be nice.

@sgrif
The current text states:

RFC #1023 is amended to state that adding a new impl to an existing trait is considered a breaking change if, given impl<P1...Pn> Trait<T1...Tn> for T0, any type T0...Tn is an uncovered type parameter (is any of P1...Pn).

However, I think this is just a hair stronger than necessary. If any of the types T0...Tn are newly added (that is, added in the same revision as the impl), then I believe it cannot be a semver breaking change.
So for example, if I have (in revision 1):
trait Trait<T> { }
struct Bar<T>

And then I attempt to add (in revision 2):
impl Trait<T> for Bar<T> { }

that would be a breaking change, as there may exist a downstream crate that has added an overlapping impl (e.g., impl Trait<Baz> for Bar<Baz>, where the downstream crate defines Baz). Unfortunate but true.
However, if I instead add (in revision 2b):
start Qux<T> { }
impl Trait<T> for Qux<T> { }

There is no way that there could have existed a downstream crate talking about Qux, and hence this ought not to be considered a semver breaking change.

@rfcbot fcp merge
I would like to propose that we merge this RFC. It serves two purposes:

To clarify and document the existing coherence rules

Existing documentation is relatively scattered

To extend the rules to cover a new case that ought to be safe

In particular, we would now permit downstream crates to add impls like the following:
impl<T> UpstreamTrait<LocalType> for UpstreamType<T>

Presently, this is disallowed because the type UpstreamType<T> does not contain any local types, and we don't permit type parameters to appear "before" local types. But — as the RFC explains — this restriction serves little purpose in practice and we can lift it without creating any (new) potential for conflict.

@rfcbot fcp concern clarify-semver
It's a minor thing, but I think we should clarify the changes that must be considered semver breaking, as described in this comment.

@rfcbot concern clarify-semver
It's a minor thing, but I think we should clarify the changes that must be considered semver breaking, as described in this comment.

@rfcbot concern sorry-about-the-delay-this-will-cause-but-i-need-to-read-this-more-in-depth-sorry-again

Someone want to check on @rfcbot?

@dwijnand you mean that it is re-adding labels all the time? It's a known issue and frankly I think the bug is at GitHub and not @rfcbot but I should fix it at some point :)

OK I forgot this was already in FCP :P

@rfcbot resolve we-can-do-better

@rfcbot resolve clarify-semver-implications

@nikomatsakis I've updated the RFC to address that concern. I think the actual answer is even more general than you've laid out here, since impl<T> Trait<Qux<T>, T> for AnyTypeOtherThanT is also fine. Ultimately the rules for whether something is a breaking change are basically the same as the rules for coherence, with the main difference that existing types are treated as non-local only for the purposes of ordering WRT uncovered type parameters.
Stating it in terms of differences from the coherence rules is super confusing to me, so I've just stated what the actual rules are. There's also a much simpler, evergreen rule that I've gone ahead and restated:
"Adding an impl for an existing trait is considered a breaking change if it could conflict with an impl a downstream crate could write"
It's worth noting, that the meaning of that rule importantly does not change with this RFC (which is laid out in https://github.com/rust-lang/rfcs/pull/2451/files#diff-c4a0a5436b92a5fea6cfa7c0367e8cb7R203).

@Centril Have you had a chance to read this more thoroughly? Is there anything I can do to help there?

@sgrif not yet sorry; I'll try to do so during the weekend :) I don't think there's anything you can do to help right now.

So... having read the RFC more in depth...
@rfcbot resolve sorry-about-the-delay-this-will-cause-but-i-need-to-read-this-more-in-depth-sorry-again
I still have some minor nits I'd like to see resolved before merging...
@rfcbot concern fix-the-nits

@rfcbot reviewed
I feel like allowing blankets to be "minor" was, if perhaps not entirely accurate, helpful for flexibility.  I wonder if we should also have something like https://scottjmaddox.github.io/Reserving-trait-impl's-in-Rust/ as part of making them major, so people can low-commitment reserve blanket impl space for the future without needing major breaking changes.

So for fairness towards the Haskell community and for accuracy, please note somehow that Haskell does have the coherence property.

I believe the most accurate statement is that Haskell has a variety of rules -- the default rules are similar to our orphan rules (in fact, that is the origin of the term 'orphan'), but authors can also "opt out" of those restrictions (e.g., via -XIncoherentInstances), which can lead to problems combining packages down the line.

The goal of the statement was to point out one of the possible ways to handle overlapping impls in a world where we don't have coherence, as evidence for why we have coherence. It was not intended as an attack or judgement on the Haskell community, but it appears to have been taken as such. I certainly don't think that fully explaining the Haskell coherence rules and how various extensions (is that the right word to use to describe {-# LANGUAGE x #-}?) is appropriate for this RFC, but I will qualify "Haskell" with "(if a discouraged flag is enabled)" if that sufficiently avoids whatever you thought I was trying to imply

@sgrif "(if a discouraged flag is enabled)" suffices :)

I've checked my box because I think this RFC is more consistent than the current semantics: that is, I think if we allow impl Trait<Local> for Foreign<Local> we ought to allow impl Trait<Local> for Foreign.
However we should have a step in the stabilization process for the libs team to consider adding impls that would become breaking changes before this becomes allowed on stable. (though we've already added technically breaking impls in the past).

@withoutboats I would note that any impls considered breaking under this RFC were intended to be considered breaking under #1023 -- the impact on breaking changes is a clarification fo wording there, not a change in what is considered breaking. Since there has been confusion over what "blanket impl" meant in the past though, I agree that it's reasonable to give a window for a breaking change here.

With the recent set of changes:
@rfcbot resolve fix-the-nits

@sgrif I don't think that's true.. an impl is breaking if it conflicts with an impl a downstream crate is allowed to write. If a downstream crate couldn't write an impl before, but now it can, that makes more impls breaking. That is, I'm considering "breaking" de facto based on code being compileable against one version and not the next, not de jure based on what rules an RFC laid out as a breaking change.

@withoutboats Fair point. Either way I agree that a window for the libs team is a good idea.

@sgrif sounds great, wanted to make sure I wasn't misunderstanding something :)

@rfcbot resolve clarify-semver
Good enough I suppose.

Huzzah! This RFC has been merged!
Tracking issue: https://github.com/rust-lang/rust/issues/55437

In cases like this, should the RFC that this supersedes get a prominent link to the RFC it is superseded by?

generally we don't mess with older RFCs, but sometimes we do. it's
certainly not required.
On Thu, Nov 1, 2018 at 5:16 AM Ralf Jung<EMAIL_ADDRESS>wrote:

In cases like this, should the RFC that this supersedes get a prominent
link to the RFC it is superseded by?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rfcs/pull/2451#issuecomment-434980439, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AABsik4qo-PmBom9dntvrE2wbwtRpX8Qks5uqrwCgaJpZM4UT83X
.


Add an option to disable docker containers in a project

Depends on https://github.com/FragileTech/ml-ops-quickstart/issues/56

[ ] offer an option to set up a new project without a docker container.
[ ] publish docker images to DockerHub / GitHub Container Registry

In progress.

I'm really curious about how you are going to implement this 😋

There are still tons of refactoring ahead. Let's see how quickly I'll merge #99

We should test when docker is disabled.

Heh. I tested and it did not work. Of course.

Oh :D
project_config["docker"] = True  # use_docker

https://github.com/FragileTech/ml-ops-quickstart/pull/109


Add tracking to the new cookie settings page

Adds tracking for:

The previous page link
The cookie details link
The save changes button

The save changes button has custom tracking, with an event label containing the consent the user has chosen, e.g: settings-no usage-yes campaigns-no

 Add tracking to the new cookies page and banner


Test Runs Failing on net5.0

Describe the bug
Firstly this may not be a bug with bUnit.  These are some observations and I would like some advice on how to log repro these issues.  Since moving our library to net5.0 our test pipeline has started giving seemingly random failures.  We almost exclusively do component testing using bUnit.  I am really not sure where to start.  Could it possibly be a timing bug with bUnit on Linux (the build server)?  I am at a loss since it seems different test fail every time so finding a pattern is very hard as you can imagine.  The below is just an example although it probably doesn't help much sorry.  This test will pass normally and will almost certainly pass if I just re-run the pipeline.
Example:
Testing this component:
<MudButton Variant="Variant.Filled" OnClick="()=>visible=true">Open</MudButton>

<MudDialog @bind-IsVisible="visible">
    <DialogContent>
        <MudText>Wabalabadubdub!</MudText>
    </DialogContent>
    <DialogActions>
        <MudButton Color="Color.Primary" OnClick="()=>visible=false">Close</MudButton>
    </DialogActions>
</MudDialog>

@code {
    public static string __description__ = "Click on open will open the inlined dialog";

    bool visible;
}

With this test:
  [TestFixture]
  public class DialogTests
  {
        private Bunit.TestContext ctx;

        [SetUp]
        public void Setup()
        {
            ctx = new Bunit.TestContext();
            ctx.AddTestServices();
        }

        [TearDown]
        public void TearDown() => ctx.Dispose();

           ///
        /// Click outside the dialog (or any other method) must update the IsVisible parameter two-way binding on close
        ///
        /// <returns></returns>
        [Test]
        public async Task InlineDialog_Should_UpdateIsVisibleOnClose()
        {
            var comp = ctx.RenderComponent<MudDialogProvider>();
            comp.Markup.Trim().Should().BeEmpty();
            var service = ctx.Services.GetService<IDialogService>() as DialogService;
            service.Should().NotBe(null);
            // displaying the component with the inline dialog only renders the open button
            var comp1 = ctx.RenderComponent<InlineDialogIsVisibleStateTest>();
            // open the dialog
            comp1.Find("button").Click();
            Console.WriteLine("\nOpened dialog: " + comp.Markup);
            comp.Find("div.mud-dialog-container").Should().NotBe(null);
            // close by click outside
            comp.Find("div.mud-overlay").Click();
            comp.Markup.Trim().Should().BeEmpty();
            // open again
            comp1.Find("button").Click();
            comp.Find("div.mud-dialog-container").Should().NotBe(null);
            // close again by click outside
            comp.Find("div.mud-overlay").Click();
            comp.Markup.Trim().Should().BeEmpty();
        }

    }

  public static class TestContextExtensions
    {
        public static void AddTestServices(this Bunit.TestContext ctx)
        {
            ctx.JSInterop.Mode = JSRuntimeMode.Loose;
            ctx.Services.AddSingleton<NavigationManager>(new MockNavigationManager());
            ctx.Services.AddMudServices(options =>
            {
                options.SnackbarConfiguration.ShowTransitionDuration = 0;
                options.SnackbarConfiguration.HideTransitionDuration = 0;
            });
            ctx.Services.AddScoped(sp => new HttpClient());
            ctx.Services.AddOptions();
        }
    }

Results in this output:

  Failed InlineDialog_Should_UpdateIsVisibleOnClose [25 ms]
  Error Message:
   Bunit.ElementNotFoundException : No elements were found that matches the selector 'div.mud-dialog-container'
  Stack Trace:
     at Bunit.RenderedFragmentExtensions.Find(IRenderedFragment renderedFragment, String cssSelector) in /_/src/bunit.web/Extensions/RenderedFragmentExtensions.cs:line 30
   at MudBlazor.UnitTests.DialogTests.InlineDialog_Should_UpdateIsVisibleOnClose() in /home/vsts/work/1/s/src/MudBlazor.UnitTests/Components/DialogTests.cs:line 123
   at NUnit.Framework.Internal.TaskAwaitAdapter.GenericAdapter`1.GetResult()
   at NUnit.Framework.Internal.AsyncToSyncAdapter.Await(Func`1 invoke)
   at NUnit.Framework.Internal.Commands.TestMethodCommand.RunTestMethod(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.TestMethodCommand.Execute(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__0()
NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
  Standard Output Messages:

 Opened dialog:

<svg class="mud-icon-root mud-svg-icon mud-inherit-text mud-icon-size-medium mr-3" focusable="false" viewBox="0 0 24 24" aria-hidden="true"><path d="M0 0h24v24H0z" fill="none"/><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg> Edit rating

Close and re-open me by clicking out of the dialog.

Expected behavior:
Passes (It does usually)
Version info:

bUnit version: preview 01
.NET Runtime and Blazor version: 5.0.3
OS type and version: buiild server Ubuntu 20.04.2

Additional context:
Passes nearly all of the time.  This is just one of seeming random failures.  All tests that have passed in the past many times.
One Thing that has chnaged that seems to have triggered these random failures is our library moving to net 5.0
cc @henon

We are using WaitForAssertion in some of our tests.

Thanks for reporting this. I am investigating a very specific test case in bUnit's test suite which always fail on linux, but never on windows.
Can you read through #329 and see if there is an overlap in the tests you are seeing fail and the one describe in that.

I already read it I was thinking that maybe the WaitForAssertion maybe causing subsequent tests to fail.  In particular one of the WaitForAssertion's that we use takes a relatively long time 200ms because we have a delay set in the component to make the UI look better.  However we seem to differ in that I think my problems started happening after moving to net 5.0  whereas you are seeing this on netcoreapp3.1 only.

Interestingly if you look at the markup from the Console.Writeline you will see that the element bUnit Doesn't find is definitely there.  I seem to remember an issue like this earlier that preview 01 resolved.

It was this issue https://github.com/egil/bUnit/issues/290

Hmm, can you confirm you are not using a nightly version of preview 1 but using the latest from nuget.org?

We are running the preview 01 from nuget.org not the nightly
We had a different but similar issue on beta 11 as per #290.  In that case the same test was failing every-time.
In this case we are having random failures in different tests.
We did start to use WaitForAssertion  fairly recently.
We don't always test locally unless doing big changes.  The tests always run on the build server for every commit/PR.

Thanks for clarifying @mikes-gh.
As for the WaitFor methods... you might need to use them when you have async operations that trigger the renders in the component, otherwise you are likely to see this issue that randomly shows up. That is expected, because the test code runs in its own thread, and the renderer runs in another. And if you trigger something from the test thread, e.g. by clicking a button, that causes the renderer to schedule a async render, e.g. due to a Task.Delay call, then you most definently need to use one of the WaitFor methods.
You can read more about it here https://bunit.egilhansen.com/docs/interaction/awaiting-async-state.html and here https://bunit.egilhansen.com/docs/verification/async-assertion.html

@egil
Understood
For our docs website we run all the docs through a render in bUnit just to check they  have no errors rendering.
I recently added some table examples that use a web service in OnInitialiseAsync to fetch data.  I have seen errors in those tests occasionally.  Is this OK?
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@namespace MudBlazor.Docs.Examples
@inject HttpClient httpClient

<MudTable Items="@Elements.Take(4)" Hover="true" Breakpoint="Breakpoint.Sm">
    <HeaderContent>
        <MudTh>Nr</MudTh>
        <MudTh>Sign</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Position</MudTh>
        <MudTh>Molar mass</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd<EMAIL_ADDRESS>        <MudTd<EMAIL_ADDRESS>        <MudTd<EMAIL_ADDRESS>        <MudTd<EMAIL_ADDRESS>        <MudTd DataLabel="Molar<EMAIL_ADDRESS>    </RowTemplate>
</MudTable>

@code {
    private IEnumerable<Element> Elements = new List<Element>();

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }
}

  [Test]
        public void TableBasicExample_Test()
        {
            ctx.RenderComponent<TableBasicExample>();
        }

If my assumption that await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable"); doesn't complete immediately, then you need to do a WaitFor*.
What happens is that you will see two renders, the first where there is no items in the Elements list, and then, async in the renderers thread, when the awaited http call returns.
You can either use WaitForState or WaitForAssertion, depending on what you are trying to do (there is a WaitForElement #252 planned).
E.g.:
[Test]
public void TableBasicExample_Test()
{
    var cut = ctx.RenderComponent<TableBasicExample>();
    cut.WaitForState(() => cut.FindAll("tbody tr").Count > 0);
}

But if I only need to know it renders without error can I just let if fly?

But if I only need to know it renders without error can I just let if fly?

Yes, you can, but that would verify that it renders with content, only that is able to render an empty list.
Question: Is that an example of a test that fails?

I did get this exception.  Strange thing is it was a real failure due to the casing of the url but it had sat without causing an exception for a long while before.  At what point does the test conclude in the situation above?
A total of 1 test files matched the specified pattern.
  Failed TableBasicExample_Test [25 ms]
  Error Message:
   System.Net.Http.HttpRequestException : Response status code does not indicate success: 404 (No matching mock handler for "GET https://localhost/webapi/periodicTable").
  Stack Trace:
     at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   at System.Net.Http.Json.HttpClientJsonExtensions.GetFromJsonAsyncCore[T](Task`1 taskResponse, JsonSerializerOptions options, CancellationToken cancellationToken)
   at MudBlazor.Docs.Examples.TableBasicExample.OnInitializedAsync() in /home/vsts/work/1/s/src/MudBlazor.Docs/Pages/Components/Table/Examples/TableBasicExample.razor:line 28
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)
   at Bunit.Rendering.TestRenderer.AssertNoUnhandledExceptions() in /_/src/bunit.core/Rendering/TestRenderer.cs:line 280
   at Bunit.Rendering.TestRenderer.Render[TResult](RenderFragment renderFragment, Func`2 activator) in /_/src/bunit.core/Rendering/TestRenderer.cs:line 164
   at Bunit.Rendering.TestRenderer.RenderFragment(RenderFragment renderFragment) in /_/src/bunit.core/Rendering/TestRenderer.cs:line 38
   at Bunit.Extensions.TestContextExtensions.RenderInsideRenderTree[TComponent](TestContextBase testContext, RenderFragment renderFragment) in /_/src/bunit.web/Extensions/TestContextExtensions.cs:line 20
   at Bunit.TestContext.Render[TComponent](RenderFragment renderFragment) in /_/src/bunit.web/TestContext.cs:line 61
   at Bunit.TestContext.RenderComponent[TComponent](ComponentParameter[] parameters) in /_/src/bunit.web/TestContext.cs:line 36
   at MudBlazor.UnitTests.Components.ExampleDocsTests.TableBasicExample_Test() in /home/vsts/work/1/s/src/MudBlazor.UnitTests/Generated/ExampleDocsTests.generated.cs:line 1124
  Skipped DatePicker_Render_Performance [< 1 ms]
  Skipped Open_Close_DateRangePicker_10000_Times_CheckPerformance [< 1 ms]
  Skipped RenderDateRangePicker_10000_Times_CheckPerformance [< 1 ms]

Also I just reran that test with a completely incorrect url and it passes.

It seems to me that there is different threading behaviour on the build server.  BTW I am using macOS at the moment.  I cant get that same test to fail locally.

At what point does the test conclude in the situation above?
...
Also I just reran that test with a completely incorrect url and it passes.

In this case, it looks like the RenderComponent method throws, as the httpClient.GetFromJsonAsync throws because of a 404 response. So in this case the error happens before the RenderComponent method returns.
That test error has nothing to do with bUnit though. The exception comes from HttpClient, so that is what you should focus on in this particular case (not saying bUnit not at fault other places). That code would fail with the same exception in a Blazor app, unless HttpClient works differently on Unix vs in the Blazor WASM/Blazor Server.

I think I am wasting your time a bit here.  I probably need to take stock and wait for another error.  At that point I think I will open a new issue.  What do you think?

I think I am wasting your time a bit here.

Not necessarily. But you are always welcome to create an issue, or if you simply have at test that you do not understand why it fails, a good place is to post a question with the test, component under test, and output in https://github.com/egil/bUnit/discussions.
Shall we close this issue for now?

Yes I will close.  When I have another seemingly random failure I will do my best to tie it down.  Certainly there is something going on on the build server that is not happening locally.  Whether it be through poorly written tests or some complex threading issues I am not sure.

I had another seemingly random failure but it was this.
We render all our docs examples to check for errors.  We don't test any assertions.
We mock api for http content retrieval using a MockHttpHandler,
Every now and then I got an exception .
I didn't know why.
But when I tested the MockHttpHandler directly it failed every time.  I had an incorrect content type.
Why does the thread not synchronise with the await call and bubble the exception back to the test thread?
This is the example
@using System.Net
@using System.Text
@namespace MudBlazor.Docs.Examples

<MudDialog DisableSidePadding="true">
    <DialogContent>
        <MudContainer Style="max-height: 300px; overflow-y: scroll">
            @if (Loading)
            {
                <MudProgressCircular Indeterminate="true"></MudProgressCircular>
            }
            else
            {
                <MudText Style="white-space: pre-wrap;">@LicenseText</MudText>
            }
        </MudContainer>
    </DialogContent>
    <DialogActions>
        <MudButton Color="Color.Primary" OnClick="Ok">Accept</MudButton>
    </DialogActions>
</MudDialog>

@code {
    [CascadingParameter] MudDialogInstance MudDialog { get; set; }

    [Inject] HttpClient HttpClient { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        Loading = true;
        var response = await HttpClient.GetAsync("https://raw.githubusercontent.com/Garderoben/MudBlazor/master/LICENSE");
        LicenseText = await response.Content.ReadAsStringAsync();
        Loading = false;
    }

    private string LicenseText;
    private bool Loading = false;

    private void Ok()
    {
        MudDialog.Close(DialogResult.Ok(true));
    }
}

And the test which is auto generated just makes sure the example renders without error
        [Test]
        public void DialogScrollableExample_Test()
        {
            ctx.RenderComponent<DialogScrollableExample>();
        }

Thanks for taking the time to report this. I am aware of the issue, and will be attempting to fix it in the next release.

@egil Is this the same as #319 ?

@egil Is this the same as #319 ?

Exactly.

@mikes-gh I just pushed a small change to how the WaitFor logic works, to work around potential race conditions/timing issue. If you want, you can try out the nightly that include the change by following this guide: https://github.com/egil/bUnit/discussions/209

@egil I dont use anyWaitFor in my code.  Would it still apply?

No, that's unlikely.


Parsing a string text results in an array of characters

If you try to display a regular string with JsonView (sometimes you can't predict the input), it renders an array of characters. I would expect the string in an "illegal scenario" to be rendered as is.

@mschipperheyn I cannot reproduce the error you described, please provide an example that can reproduce the error.

I've added a sandbox here
IMHO JsonView should deal with plain strings in a way that displays it normally

@mschipperheyn This package is for JSON preview, not a string preview tool.
- <ReactJsonView value="data" />;
+ <ReactJsonView value={{ a: "data" }} />;

hmmm lots of folks do have json objects or strings. It'd be great to not have to worry about simple strings, and have them match the theme.


Feature: allow classnames on nodes

as I use addClassNamesToElement I would like those class names to be stored in the editorstate somehow so that when exporting and importing they are persisted

https://lexical.dev/docs/concepts/serialization


fix: added optional chaining for conditions in dr details page

issue

/assign @SanjalKatiyar

/approve
/lgtm


[monitor-ingestion] Change default concurrency to 5

Packages impacted by this PR

@azure/monitor-ingestion

Describe the problem that is addressed by this PR
The default concurrency value was discussed in the arch board review. After doing some perf analysis and a follow-up discussion with Jose, we settled on setting the concurrency to 5 by default (in line with .NET). This PR implements that plus adds a bit of documentation and a sample.

API change check
API changes are not detected in this pull request.


Cherry pick: iOS context menu positioning

This cherry picks https://github.com/flutter/flutter/pull/119565, which was a small fix to the math that positions the iOS text selection toolbar when it's too close to the top of the screen.  This should be a low-risk change.
Some changes in that PR were made to files that don't exist yet in this candidate branch, so I have ignored those changes.
Closes https://github.com/flutter/flutter/issues/121307
CC @limenote135

the codesign failures are expected, but I am not sure about the the linux docs_test failure

Ah those docs errors are artifacts of the merge, those classes truly don't exist yet.  I just removed them.


[Bug]1.2.3alpha运行一段时间后报错

Describe the bug【描述 bug】
客户端quic运行一段时间后无法连接，看status提示faill，手动restart service
To Reproduce【如何复现该bug】
时间长后，估计12小时？
Expected behavior【预期的行为】
无法连接
Envs (please complete the following information):【系统环境】
服务端x86，123alpha， ipv6 only vps；客户端arm64，123alpha；
Config file 【配置文件，客户端服务端配置都提供】
#insecure = true
#utls = true #quic无法使用utls, 没办法
advancedLayer = "quic"
early = true
extra = { congestion_control = "hy", mbps = 3000 }
#alpn = ["asdfsadf"]    # 如果alpn没指定

Debug Log 【Debug日志】
Active: failed (Result: exit-code) since Sat 2022-05-14 05:10:15 CST; 4h 3min ago
    Process: 26896 ExecStart=/vs/verysimple -c t/vs/quic.toml (code=exited, status=2)
   Main PID: 26896 (code=exited, status=2)

May 14 05:10:16 ub22 verysimple[26896]: github.com/e1732a364fed/v2ray_simple.handshakeInserver(0x4001038840)
May 14 05:10:16 ub22 verysimple[26896]:         github.com/e1732a364fed/v2ray_simple/main.go:387 +0x144
May 14 05:10:16 ub22 verysimple[26896]: github.com/e1732a364fed/v2ray_simple.handshakeInserver_and_passToOutCli>May 14 05:10:16 ub22 verysimple[26896]:         github.com/e1732a364fed/v2ray_simple/main.go:499 +0x80
May 14 05:10:16 ub22 verysimple[26896]: github.com/e1732a364fed/v2ray_simple.handleNewIncomeConnection({0x80466>May 14 05:10:16 ub22 verysimple[26896]:         github.com/e1732a364fed/v2ray_simple/main.go:369 +0xeb8
May 14 05:10:16 ub22 verysimple[26896]: github.com/e1732a364fed/v2ray_simple.ListenSer.func2({0x803070?, 0x4000>May 14 05:10:16 ub22 verysimple[26896]:         github.com/e1732a364fed/v2ray_simple/main.go:139 +0x4c
May 14 05:10:16 ub22 verysimple[26896]: created by github.com/e1732a364fed/v2ray_simple/netLayer.loopAccept
May 14 05:10:16 ub22 verysimple[26896]:         github.com/e1732a364fed/v2ray_simple/netLayer/listen.go:56 +0x2>

Other 【其他】
【注意，配置文件和客户端服务端配置 太长的话，前后加上三个 ```】

发上你的 日志文件。直接上传文件即可，或者你精简一下日志的内容再上传上来，主要是要看全整个 panic 信息。

发上你的 日志文件。直接上传文件即可，或者你精简一下日志的内容再上传上来，主要是要看全整个 panic 信息。

已经restart了， journalctl -u verysimple.service  好像只有新的了。 等待再次出现吧…… 5点时候应该不在用

发上你的 日志文件。直接上传文件即可，或者你精简一下日志的内容再上传上来，主要是要看全整个 panic 信息。

已经restart了， journalctl -u verysimple.service 好像只有新的了。 等待再次出现吧…… 5点时候应该不在用

不是 journal那个啊！
verysimple会自己生成日志文件的。

找到了  在/vs_log …… 改了下地址 其他没动.， “……”处都是重复
{"L":"ERROR","T":"220514 054733.186","M":"Super AdvLayer GetCommonConn failed","connid":972103,"error":"INTERNAL_ERROR: write udp [::]:35244->[2111:4f8:30cc:32a1:1234:3224:319:1]:443: sendto: network is unreachable"}
{"L":"WARN ","T":"220514 054736.199","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 054736.200","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"INFO ","T":"220514 054736.200","M":"New Accepted Conn","connid":812784,"from":"<IP_ADDRESS>:56076","handler":"tcp+socks5://<IP_ADDRESS>:5380"}
{"L":"INFO ","T":"220514 054736.205","M":"Request","connid":812784,"from":"<IP_ADDRESS>:56076","target":"tcp://<IP_ADDRESS>:443","through":"udp+tls+quic+vless://molezz.xyz:443"}
{"L":"ERROR","T":"220514 054736.207","M":"Super AdvLayer GetCommonConn failed","connid":812784,"error":"lookup molezz.xyz on <IP_ADDRESS>:53: dial udp <IP_ADDRESS>:53: socket: too many open files"}
{"L":"INFO ","T":"220514 054739.337","M":"New Accepted Conn","connid":871591,"from":"<IP_ADDRESS>:56138","handler":"tcp+socks5://<IP_ADDRESS>:5380"}
{"L":"INFO ","T":"220514 054739.347","M":"Request","connid":871591,"from":"<IP_ADDRESS>:56138","target":"tcp://<IP_ADDRESS>:443","through":"udp+tls+quic+vless://molezz.xyz:443"}
{"L":"WARN ","T":"220514 054739.336","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 054739.349","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"ERROR","T":"220514 054739.351","M":"Super AdvLayer GetCommonConn failed","connid":871591,"error":"lookup molezz.xyz on <IP_ADDRESS>:53: dial udp <IP_ADDRESS>:53: socket: too many open files"}
{"L":"WARN ","T":"220514 054749.368","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 054749.368","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"INFO ","T":"220514 054749.369","M":"New Accepted Conn","connid":449843,"from":"<IP_ADDRESS>:56232","handler":"tcp+socks5://<IP_ADDRESS>:5380"}
{"L":"WARN ","T":"220514 054753.204","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 054753.454","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 054753.955","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}

………………………………………………………………

{"L":"WARN ","T":"220514 055012.445","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 055012.445","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 055012.946","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 055012.946","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 055013.450","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 055013.450","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 055013.951","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 055013.952","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 055014.453","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 055014.453","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"INFO ","T":"220514 062003.106","M":"Program started"}
{"L":"INFO ","T":"220514 062003.189","M":"zap log init complete.","logfile":"/root/vs/vs_log"}
{"L":"INFO ","T":"220514 062003.189","M":"Working at","dir":"/"}
{"L":"INFO ","T":"220514 062003.189","M":"Options","Log Level":"info","UseReadv":true}

你这个也没panic啊，
你再日志文件里找一找有没有panic的
两个10M的也要找。谁知道你那个panic是在哪个日志文件里发生的，都要找

还有，你的 mbps 参数给的太高了。实际使用时不可能这么高，除非你上传速度真能达到 3000mbps （3Gbps的网络，谁有？）
你可以调低到 100mbps

没搜到panic啊。 那我client先改成30mbps看看了，家宽  。3000 我以为默认的参数就先没动了……
[app]
logfile = "/vs/vs_log"
[[listen]]
protocol = "socks5"
host = "<IP_ADDRESS>"
port = 5380

[[listen]]
protocol = "http"
host = "<IP_ADDRESS>"
port = 8010
# noroute = true

[[dial]]
protocol = "vlesss"
uuid = "51231231232cb"
host = "aaaaaa"
port = 2443
version = 0
#insecure = true
#utls = true #quic无法使用utls, 没办法
advancedLayer = "quic"
early = true
extra = { congestion_control = "hy", mbps = 30 }

另外就是你这里 too  many open files 太多了。 你是开启了 fullcone吗？ 开启fullcone时间长 就会造成这种情况。

这个没特别设置过， 但是路由开了upnp ，<IP_ADDRESS>	41642	NAT-PMP 41642 udp
全锥？

这个没特别设置过， 但是路由开了upnp ，<IP_ADDRESS> 41642 NAT-PMP 41642 udp 全锥？

我问的意思是，配置文件中有没有 写过 “fullcone = true”，如果在 direct 写过这一行，可以注释掉再试试。

不过，也许是 quic 时间长了就会出现这种问题？ 没长时间试过。

这个没特别设置过， 但是路由开了upnp ，<IP_ADDRESS> 41642 NAT-PMP 41642 udp 全锥？

我问的意思是，配置文件中有没有 写过 “fullcone = true”，如果在 direct 写过这一行，可以注释掉再试试。

确认了下，没有写。暂时都是尝试sample里的参数

直到给出 panic完整信息前，我无法给出准确意见。

还是没有搜索到“panic”， 最后还是死循环在too many……
 Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213518.684","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213518.684","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213519.185","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213519.185","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213519.686","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213519.686","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213520.187","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213520.188","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213520.688","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213520.689","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213521.190","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213521.190","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213521.691","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213521.691","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213522.192","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213522.192","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213522.693","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213522.694","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213523.195","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213523.195","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213523.697","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213523.697","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213524.198","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213524.199","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213524.700","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213524.700","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213525.201","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213525.202","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213525.703","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213525.703","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213526.204","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213526.204","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213526.705","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213526.706","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213527.207","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213527.207","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213527.709","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213527.709","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213528.210","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213528.211","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213528.712","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213528.713","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213529.214","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213529.215","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213529.716","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213529.716","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213530.218","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213530.218","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213530.721","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213530.721","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213531.222","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213531.222","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213531.724","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213531.724","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213532.225","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213532.225","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213532.727","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213532.727","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213533.228","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}
{"L":"WARN ","T":"220514 213533.229","M":"Too many incoming conns! Will Sleep.","err":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files","tooManyRetryCount":1}
{"L":"WARN ","T":"220514 213533.732","M":"failed to accept connection","error":"accept tcp <IP_ADDRESS>:5380: accept4: too many open files"}

vs_log-2022-05-15T01-58-13.719.log

我让你开debug日志，你不开，能听话吗？

目前的推测是 目前 vs的实现 有点缺陷， 没有完美关闭所有的连接，导致悬垂连接越来越多，最后导致 too many问题。
但是我需要证据。你两端均 删除原来所有日志文件，开启 debug日志，在测试一天，遇到连不上问题后，把两端所有的日志全上传上来

原来是这样， 明白了，重启了
[app]
logfile = "/vs/vs_log"
loglevel = 0

有点复杂啊，文件也爆了
服务端一个文件
server-vs.log
客户端10个too many了
 10M May 15 18:41 vs_log-2022-05-15T10-41-00.746
 10M May 15 18:41 vs_log-2022-05-15T10-41-22.513
 10M May 15 18:41 vs_log-2022-05-15T10-41-45.262
 10M May 15 18:42 vs_log-2022-05-15T10-42-17.134
 10M May 15 18:42 vs_log-2022-05-15T10-42-42.704
 10M May 15 18:43 vs_log-2022-05-15T10-43-06.836
 10M May 15 18:43 vs_log-2022-05-15T10-43-31.575
 10M May 15 18:43 vs_log-2022-05-15T10-43-56.014
 10M May 15 18:44 vs_log-2022-05-15T10-44-18.074
 10M May 15 18:44 vs_log-2022-05-15T10-44-42.999

     Loaded: loaded (/etc/systemd/system/verysimple.service; enabled; vendor preset: enabled)
    Drop-In: /run/systemd/system/service.d
             └─zzz-lxc-service.conf
     Active: active (running) since Sun 2022-05-15 10:52:33 CST; 9h ago
   Main PID: 6141 (verysimple)
      Tasks: 11 (limit: 1913)
     Memory: 110.5M
     CGroup: /system.slice/verysimple.service
             └─6141 /vs/verysimple -c /vs/quic.toml

May 15 20:36:24 ub22 verysimple[6141]: 2022-05-15 12:36:24.105        WARN        Too many incoming conns! Will Sleep.        {"err": "accept tcp <IP_ADDRESS>:5380: accept4: >May 15 20:36:24 ub22 verysimple[6141]: 2022-05-15 12:36:24.105032386 +0000 UTC m=+35030.104468255 write error: can't open new logfile: open /vs/vs_log: too many open filesMay 15 20:36:24 ub22 verysimple[6141]: 2022-05-15 12:36:24.605        WARN        failed to accept connection        {"error": "accept tcp <IP_ADDRESS>:5380: accept4: too man>May 15 20:36:24 ub22 verysimple[6141]: 2022-05-15 12:36:24.605654064 +0000 UTC m=+35030.605089933 write error: can't open new logfile: open /vs/vs_log: too many open filesMay 15 20:36:24 ub22 verysimple[6141]: 2022-05-15 12:36:24.605        WARN        Too many incoming conns! Will Sleep.        {"err": "accept tcp <IP_ADDRESS>:5380: accept4: >May 15 20:36:24 ub22 verysimple[6141]: 2022-05-15 12:36:24.605959612 +0000 UTC m=+35030.605395647 write error: can't open new logfile: open /vs/vs_log: too many open filesMay 15 20:36:25 ub22 verysimple[6141]: 2022-05-15 12:36:25.106        WARN        failed to accept connection        {"error": "accept tcp <IP_ADDRESS>:5380: accept4: too man>May 15 20:36:25 ub22 verysimple[6141]: 2022-05-15 12:36:25.106889713 +0000 UTC m=+35031.106325540 write error: can't open new logfile: open /vs/vs_log: too many open filesMay 15 20:36:25 ub22 verysimple[6141]: 2022-05-15 12:36:25.107        WARN        Too many incoming conns! Will Sleep.        {"err": "accept tcp <IP_ADDRESS>:5380: accept4: >May 15 20:36:25 ub22 verysimple[6141]: 2022-05-15 12:36:25.107200094 +0000 UTC m=+35031.106635963 write error: can't open new logfile: open /vs/vs_log: too many open fileslines 1-21/21 (END)

可能覆盖了 ，几个文件内容一样
{"L":"DEBUG","T":"220515 104100.737","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.738","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.738","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.738","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.738","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.738","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.738","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.739","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.739","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.739","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.739","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.739","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.739","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.740","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.740","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.740","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.740","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.741","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.741","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.741","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.741","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.741","M":"Get RandPort udp but got err, trying again"}
{"L":"DEBUG","T":"220515 104100.741","M":"Get RandPort udp but got err, trying again"}

上传你整个 服务端和 客户端的配置文件。
你客户端10个文件好歹给我上传一两个啊？？
不要我一个一个命令你上传好不好，bug模板里早要求上传了，你给我几行配置不行，我要完整的配置。
再次强调，要听话。不听话我可不帮你了。
目前推测是socks5 不断地使用 udp associate 导致占满了所有udp 端口。但是我需要证据，你是用的socks5吗？

对 socks5. 服务端log见上贴， 发现时客户端10个都是18：41-18：44生成的一样的， 所以就只截了一段。 这两个第一个1841和最后个1844.
vs_log-2022-05-15T10-44-42.999.log
vs_log-2022-05-15T10-41-00.746.log
client
[app]
logfile = "/vs/vs_log"
loglevel = 0

[[listen]]
protocol = "socks5"
host = "<IP_ADDRESS>"
port = 5380

[[listen]]
protocol = "http"
host = "<IP_ADDRESS>"
port = 8010
# noroute = true

[[dial]]
protocol = "vlesss"
uuid = "11111111111"
host = "xx.xx"
port = 2443
version = 0
#insecure = true
#utls = true #quic无法使用utls, 没办法
advancedLayer = "quic"
early = true
extra = { congestion_control = "hy", mbps = 30 }
#alpn = ["asdfsadf"]    # 如果alpn没指定，则会自动使用 "h3"作为alpn，quic包的限制，导致必须指定一个alpn

# 另外，你若想兼容现有其它 quic 客户端/服务端，你需要配置它们的 alpn 为 h3 或者这里配置的值才行

# 比如v2ray/xray，你要配置 tlsSettings里的 alpn 为 h3 ，才能连上 verysimple 的 quic

# 只要 advancedLayer 设成了quic，network 就会自动被配置为udp，所以不需手动指定udp

# 同时，因为quic的限制，一旦  advancedLayer 设成了quic， 你就必须要保证tls是开启的状态，
#  要不就是在 vless 后面加个s变成 vlesss, 要不就明确指出 tls = true

# tls = true

# 我们可以选择性使用 “hysteria 阻塞控制” 方法, 但是协议依然为quic协议。具体请参考本作作者对hysteria的讨论
# 不想用hy阻控的话就注释掉.

#因为我们不使用hysteria协议头，所以不用单独标注 上行流量和下行流量, 因为我们不与服务端协商
# 也就是说, hysteria协议头 是会去协商 出一个 最低速度, 而实际上因为服务端和客户端都是自己配置好的,
# 我们早知道最低速度了. hy阻控 显然也不适合机场. 所以我们不协商速度, 直接在发送方设置即可.
#
# 我们这里统一是上行。因为只有发送方 可以控制这个阻塞控制速度的 参数
# 这里我们配置为所在网络最大上传带宽即可.

# 比如我们client.toml里配置 那就是 【客户端的最大上传速度、服务端的最大下载速度】的最小值，server.toml里配置对我们客户端来说就是 【客户端的最大下载速度、服务端的最大上传速度】的最小值.

# 实测似乎mac上quic最大的网速就只能够达到 1400mbps左右，配置再大的数也没用

server
[app]
logfile = "/vs/vs_log"
loglevel = 0

[[listen]]
protocol = "vlesss"
uuid = "123333333333"
host = "<IP_ADDRESS>"
port = 2443
version = 0
#insecure = true
fallback = ":80"
cert = "/root/.acme.sh/cer"
key = "/root/.acme.sh/key"
advancedLayer = "quic"
#alpn = ["asdfsadf"]    #如果指定alpn，则客户端和服务端都要指定，而且要相同
early = true
# hy_manual的意思是手动挡, 注意, 你要想提高下载速度，需要手动调节服务端的挡;
#extra = { congestion_control = "hy", mbps = 200, hy_manual = true }
extra = { congestion_control = "hy", mbps = 300 }
#extra = { maxStreamCountInOneSession = 6 }  # maxStreamCountInOneSession默认为4. 该值越大, 对浏览网页的延迟降低越多，但是对下载、测速等情况的负优化越大. 鱼和熊掌不可兼得. 自行调节. 如果调为1, 就相当于 单路单用

[[dial]]
protocol = "direct"

你这个客户端的socks5，是正常的socks5吗？  你的电脑是直接连接这个socks5端口吗？
还是说，你是否用了什么其它 tun2socks 等机制 给 该socks5 提供 用户数据呢？

我新修改了代码，你可以编译试试，最新代码不会造成上面两个无限循环问题，而是会在遇到20个问题后就退出循环。这样可以更快地找到问题

我这用这个协议的小众吧。
N1arm盒子客户端连服务器，开启socks5：5380.
然后openwrt中用pw插件socks5连客户端。作为旁路网关

我这用这个协议的小众吧。 N1arm盒子客户端连服务器，开启socks5：5380. 然后openwrt中用pw插件socks5连客户端。作为旁路网关

果然如我所料。
那么基本上确认 和 quic没什么关系，应该是 socks5的udp代码的问题。
我先关闭该issue了，继续关注 #97 即可。
如果 97 解决了 还是有问题，再重开该issue。


Fix crash when there's nothing to install

Make sure not to call 'Opam.install' with an empty list, which results in an error. Messages are planned for this situation but the error happen before they could be printed.

I'm not adding a test for this because I think the heavy docker tests wouldn't be a good fit. We need a quicker test framework first.

I'll add the changelog after the CI has run to avoid wasting an hour and I'll cancel the jobs triggered after that.


[BEAM-3130] View.asMap() causes a ClassCastException in Apex runner

Follow this checklist to help us incorporate your contribution quickly and easily:

[ ] Make sure there is a JIRA issue filed for the change (usually before you start working on it).  Trivial changes like typos do not require a JIRA issue.  Your pull request should address just this issue, without pulling in other changes.
[ ] Each commit in the pull request should have a meaningful subject line and body.
[ ] Format the pull request title like [BEAM-XXX] Fixes bug in ApproximateQuantiles, where you replace BEAM-XXX with the appropriate JIRA issue.
[ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
[ ] Run mvn clean verify to make sure basic checks pass. A more thorough check will be performed on your pull request automatically.
[ ] If this contribution is large, please file an Apache Individual Contributor License Agreement.

R: @jkff

Thanks! Is it possible to add some tests for this?

@jkff tests are added

Thank you! While trying to merge this, I noticed a much more serious issue that I believe should be resolved before this one: https://issues.apache.org/jira/browse/BEAM-3261 - could you take a look?

@jkff I'm aware of that issue as well. It is certainly important, but at the same time it's not new and I don't see why it needs to be resolved in order for this change to be merged.

Fair enough, the current PR is an improvement in any case. Simplified the test a little bit and merged.


Uppdated to support 0.45

Is it going to be updated to support the new API when it have been released?

Yes.


Logging manipulation API from rmw_connext

This follows a series of changes on all the DDS specific implementation to let user programs manipulate logging levels.
Connect to ros2/rmw#124

@dirk-thomas @dhood Could you please review this patch? This is connected to another approved patch by Dirk

Could you please review this patch?

I am still waiting for an answer on my previous question.


Support Specifying Partitions for Streaming

As a consumer
I want to specify the partitions I want my stream to be assigned to
So that I can do load balance on my own.
If we implement https://nakadi.io/manual.html#/subscriptions/subscription_id/events_post to start streaming on a subscription we can offer the optional parameter partitions. This may be done backwards compatible to today's API using https://nakadi.io/manual.html#/subscriptions/subscription_id/events_get.

So, after some research, there are 2 option to fix this issue:

rethink the design of the library to clearly separate implementations for High- and Low-level APIs
deprecate the Low-level API fully and fully concentrate on the subscription model of the API

Reference in the nakadi docs: https://nakadi.io/manual.html#/event-types/name/events_get
It is impossible to start streaming with POST request for the low-level API.

One more thing. It is possible to go with "turn it around" approach. Every StreamBuilder will pass a lambda callback down to the NakadiReader specifying the particular logic for each time of API, and then the reader will just be responsible for the execution and actual reading the stream.
Reference: https://github.com/zalando-nakadi/fahrschein/blob/master/fahrschein/src/main/java/org/zalando/fahrschein/NakadiReader.java#L149

NakadiReader already has several places where the logic differs depending on whether a subscription exists, adding one more probably does not hurt. Longer term we should probably deprecate the low level api to clean this up. Are there any plans from the nakadi project to actually remove the low level api at some point? (I think it is already deprecated, right?)

@jhorstmann Yes, as they've posted in the official documentation, all low-level related API functions are already marked as deprecated, so it definitely does make sense to remove all of this functionality.

Let's not add more features to the deprecated low-level API. @lukasniemeier-zalando any objections?


Output Points Number is different from C++ when I decimate a stl model

In python:
mesh = vedo.load(os.path.join(mesh_path, mesh))
target_num = 10000
ratio = target_num/mesh.NCells()
mesh_d = mesh.clone()
mesh_d.decimate(fraction=ratio)

I got 5380 points.
In C++:
vtkNew<vtkDecimatePro> decimate_a;
decimate_a->BoundaryVertexDeletionOn();
decimate_a->SetInputData(stl_reader->GetOutput());
decimate_a->SetTargetReduction(1-ratio_d);
decimate_a->Update();
vtkSmartPointer<vtkPolyData> Polydata_d_a;
Polydata_d_a = decimate_a->GetOutput();

I got 5884 points.
And here is my model:
sample.zip

You need to use the "pro" algorithm (default is "quadric"):
mesh.decimate(fraction=ratio, method="pro").printInfo()
also the decimation is related to points not cells.. so the ratio should be calculated based on
ratio = target_num/mesh.NPoints()


Label on segment?

Hi, is there anyway to add a label to each segment? could this be added?

I wasn't thinking of adding labels to the segments since a lot of design related issues need to be solved. Will think about it. In the meantime, you're always welcome to contribute!


Replace "Edit with multiple Vims" with "Edit with Vim using tabpages" (Issue #8404)

This change only applies to the Windows version of Gvim.

Hi Ken,
I'm obviously not familiar with using github's pull requests and so when I tried to reply to your comment, the reply apparently became a commit in my fork.  Shall I cancel my pull request,  fix the fork and then resubmit the pull request?  If there's a simpler approach, please advise.
Sorry for the trouble.
-mike

Shall I cancel my pull request,

No need to do that.
If you want, you can use git push -f to amend your commits.


Add min size for row num column

fixes #2511

@anthonydresser I'll merge this now to pick-up in tonight's insiders build.


Revert "issue 1960 private to public"

Reverts microsoft/botbuilder-dotnet#2117

Reverting based on compat break.


feat(infra): terraform to be able to setup bridge

Adding into the repo the TF code to be able to setup bridge

Are we going to have multiple lambdas?
If we're not going to have that many then I think we probably want to not throw things in modules. That said. I'm happy to throw them in well named modules :D


fixed responsiveness for parent home page

Description
This is another page we have made responsive - still some more to go.
Fixes # (issue)
## Loom Video
Type of change
Please delete options that are not relevant.

[x] Bug fix (non-breaking change which fixes an issue)

Checklist:

[x] My code follows the style guidelines of this project
[x] I have performed a self-review of my own code
[x] I have removed unnecessary comments/console logs from my code
[x] I have made corresponding changes to the documentation if necessary (optional)
[x] My changes generate no new warnings
[x] I have checked my code and corrected any misspellings
[x] No duplicate code left within changed files
[x] Size of pull request kept to a minimum
[x] Pull request description clearly describes changes made & motivations for said changes

@EmmS21 and i worked on this one together


Azure Functions Cli

CLI:
Commands:

[x] web
[x] run
[x] cert
[x] git-init
[x] git-pull
[x] git-push
[x] new
[x] list
[x] login
[x] logout
[x] open
[x] switch-tenants
[x] kill

Not Commands:

[x] Make run command faster
[x] Update help text for all commands
[x] Add tests

Maybes?

[x] Remove dependency on https://github.com/gsscoder/commandline

2 proposed first time experiences for the CLI:
Local -> Azure:
> mkdir functions
> cd functions
> azf git-init
> azf new function # launches yoeman generator (assume functionName=HttpCSharp)
> azf run HttpCSharp -f file.json
> git commit -am "First function"
> azf new functionapp MyNewAwesomeFunctionApp -l WestUS
> azf git-push MyNewAwesomeFunctionApp master
> azf open MyNewAwesomeFunctionApp # launches default web browser with deep link to portal

Azure -> Local:
> azf login # optional
> azf list functionapps # displays a list of function apps
> azf switch-tenants # displays a list of tenants
> azf switch-tenants <tenantId>
> azf list functionapps
> azf git-clone MyNewAwesomeFunctionApp
> cd MyNewAwesomeFunctionApp
> azf web # then you go in the portal and switch to local

Thoughts on the proposed interface?
> azf help
azf (AzureFunctions) 0.1
Copyright (C) 2016 Microsoft
Usage: azf <command> [--options]

  git-pull          Performs the git command with the remote being the function app
  git-clone         Performs the git command with the remote being the function app
  git-push          Performs the git command with the remote being the function app
  git-fetch         Performs the git command with the remote being the function app
  kill              Kills running server instances of azf
  login             Clears login cache and prompts for a new login
  logout            Clears login cache
  open              Launche default browser with link to functionApp in https://portal.azure.com
  st                List and switche current tenant for the Cli
  switch-tenants    List and switche current tenant for the Cli
  cert              Automate `netsh http` to setup SSL and UrlAcls
  git-config        Not yet Implemented
  git-init          Creates .gitignore, and host.json. Runs `git init .`
  list              Lists function apps in current tenant. See `switch-tenant` command
  gs                Not yet Implemented
  get-settings      Not yet Implemented
  new               Handle creating a new Function or FunctionApp
  run               Run the specified function locally
  web               Launches a Functions server endpoint locally

>  azf help new
azf (AzureFunctions) 0.1
Copyright (C) 2016 Microsoft
Usage: azf new [function/functionApp] <functionAppName> [--options]

  -s, --subscription    Subscription to create function app in
  -l, --location        (Default: WestUS) Geographical location for your function app
  --logFile             Log file path. If not specified, all traces go to Console
  --quiet               (Default: False) Disable all logging

Hi @ahmelsayed, I'm your friendly neighborhood .NET Foundation Pull Request Bot (You can call me DNFBOT). Thanks for your contribution!
You've already signed the contribution license agreement. Thanks!
The agreement was validated by .NET Foundation and real humans are currently evaluating your PR.
TTYL, DNFBOT;

Hi @ahmelsayed, as a .Net developer doing Node development, this is the interface I would be most comfortable with. Especially since I use a Mac and Atom for my development environment.
The command are logical, well thought out and not surprising. That's always a plus.

You'll want to add entries to WebJobs.Script.proj so this is building on the CI machine and tests are running. @fabiocav can also help you make sure artifacts are being generated as part of our AppVeyor build (we'll want to start including these in our milestone release drops, e.g. here).

Also you'll want to start a wiki page on how to use the CLI :) At least getting people started.

Took a high level pass. Not a lot of feedback on the actual implementation, but here are a couple of points in addition to the comments I've left:

bit of a nit (and often source of much debate), but we may want to add the "Async" suffix to Task returning methods to follow the convention used in the project.
There are several spots where we're missing brackets on if statements and others, enabling the checks Mathew mentioned should point those out.

@mathewc @fabiocav I addressed all the comments, except for renaming the functions that return Tasks to end in Async. Do I really have to do that :) If it's a style issue for the project, I've no problem renaming them, just encourage you to re-question the style. I know that it's a debatable thing, but the way I look at it, if there is only 1 option for an API (that is async, no sync version) and it's clear from the definition that it returns task, it's it implicit and clear that it's an async function? Adding a prefix to the name seems redundant.

Oh, need to play with it now since I'm sure 0326a20 made is so pretty
Now all we need is some ASCII art! :)

:) not all commands have colors now, but yes, I was hoping that adding some color would make the output and help more readable, especially in error scenarios or scenarios that require user action.

0.0.10 isn't installing on npm -

npm install -g azurefunctions
npm ERR! cb() never called!

0.0.9 installs successfully

you most probably have a server already running in the background. try running func kill to see what's running and func kill -a if you want to kill all of them.

Still a failure:

can you try npm cache clean?

Still having issues running this on my machine. I'm getting an error thrown from Ln23 of ConsoleApp.cs. This repros on 0.0.9 as well.
public static void Run<T>(string[] args, IDependencyResolver dependencyResolver = null)
        {
            Task.Run(() => RunAsync<T>(args, dependencyResolver)).Wait();
        }

Exception thrown: 'Microsoft.WindowsAzure.Storage.StorageException' in Microsoft.WindowsAzure.Storage.dll
Exception thrown: 'System.InvalidOperationException' in mscorlib.dll
Exception thrown: 'System.AggregateException' in mscorlib.dll
Exception thrown: 'System.IO.FileNotFoundException' in mscorlib.dll
Exception thrown: 'Microsoft.WindowsAzure.Storage.StorageException' in Microsoft.WindowsAzure.Storage.dll
The thread 0xa20 has exited with code 0 (0x0).
Exception thrown: 'Microsoft.WindowsAzure.Storage.StorageException' in Microsoft.WindowsAzure.Storage.dll
Exception thrown: 'System.InvalidOperationException' in mscorlib.dll
Exception thrown: 'System.AggregateException' in mscorlib.dll
The program '[14168] Func.vshost.exe' has exited with code -1 (0xffffffff).

Looks like Storage issues? I tried setting environment variables/etc.
I am also still getting install issues with 0.0.10, but I manually grabbed the tarball, unzipped it, and placed it in my global npm. It runs fine, except for web/run.
> func run .\httptest\
Response Status Code: ServiceUnavailable

It's quite hard to tell if I'm doing something wrong or if it's just not functional. Attaching a debugger only kept me going through a loop where I was getting the above exceptions being thrown.
Ideas for next steps?

are you running Func.vshost.exe or func.exe? also it might be a legitimate issue. Maybe I have some storage dll globally in my gac or something and it's not included in the package.

Also the web command is the only command that actually loads the host, so it's the one most likely to fail because of a missing dependency.

I'm not running func.exe/func.vshost.exe directly in either case. In one, I attached the debugger to the source in your fork to find where the exception was being thrown. In the other, it was just the npm package that gets installed from npm registry. I tried attaching to the host to see if I can find in more detail what was causing the host to not start, but symbols weren't loading for the script.host

Also, I realized I didn't give verbose logs for the npm install issue:
C:\Users\chrande> npm cache clean
C:\Users\chrande> npm install -g azurefunctions --verbose
npm info it worked if it ends with ok
npm verb cli [ 'C:\\Program Files\\nodejs\\node.exe',
npm verb cli   'C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js',
npm verb cli   'install',
npm verb cli   '-g',
npm verb cli   'azurefunctions',
npm verb cli   '--verbose' ]
npm info using<EMAIL_ADDRESS>npm info using<EMAIL_ADDRESS>npm verb request uri https://registry.npmjs.org/azurefunctions
npm verb request no auth needed
npm info attempt registry request try #1 at 10:40:23 AM
npm verb request id f95c9ebcb62b4b9a
npm http request GET https://registry.npmjs.org/azurefunctions
npm http 200 https://registry.npmjs.org/azurefunctions
npm verb headers { server: 'CouchDB/1.5.0 (Erlang OTP/R16B03)',
npm verb headers   etag: '"27SBPYMH9HQDLMHKR46X8VOFY"',
npm verb headers   'content-type': 'application/json',
npm verb headers   'content-encoding': 'gzip',
npm verb headers   'cache-control': 'max-age=300',
npm verb headers   'content-length': '1796',
npm verb headers   'accept-ranges': 'bytes',
npm verb headers   date: 'Tue, 09 Aug 2016 17:40:27 GMT',
npm verb headers   via: '1.1 varnish',
npm verb headers   age: '0',
npm verb headers   connection: 'keep-alive',
npm verb headers   'x-served-by': 'cache-sjc3622-SJC',
npm verb headers   'x-cache': 'MISS',
npm verb headers   'x-cache-hits': '0',
npm verb headers   'x-timer': 'S1470764427.365202,VS0,VE142',
npm verb headers   vary: 'Accept-Encoding' }
npm verb get saving azurefunctions to C:\Users\chrande\AppData\Roaming\npm-cache\registry.npmjs.org\azurefunctions\.cach
e.json
npm verb correctMkdir C:\Users\chrande\AppData\Roaming\npm-cache correctMkdir not in flight; initializing
npm verb makeDirectory C:\Users\chrande\AppData\Roaming\npm-cache creation not in flight; initializing
npm verb makeCacheDir UID & GID are irrelevant on win32
npm verb cache add spec azurefunctions
npm verb addNamed "latest" is being treated as a dist-tag for azurefunctions
npm info addNameTag [ 'azurefunctions', 'latest' ]
npm verb addNameTag registry:https://registry.npmjs.org/azurefunctions not in flight; fetching
npm verb get https://registry.npmjs.org/azurefunctions not expired, no request
npm verb addNamed "0.0.10" is a plain semver version for azurefunctions
npm verb addRemoteTarball https://registry.npmjs.org/azurefunctions/-/azurefunctions-0.0.10.tgz not in flight; adding
npm verb addRemoteTarball [ 'https://registry.npmjs.org/azurefunctions/-/azurefunctions-0.0.10.tgz',
npm verb addRemoteTarball   '51f6bce1e29f4d037421255b9b370822e75605a3' ]
npm info retry fetch attempt 1 at 10:40:24 AM
npm info attempt registry request try #1 at 10:40:24 AM
npm http fetch GET https://registry.npmjs.org/azurefunctions/-/azurefunctions-0.0.10.tgz
npm http fetch 200 https://registry.npmjs.org/azurefunctions/-/azurefunctions-0.0.10.tgz
npm verb addTmpTarball C:\Users\chrande\AppData\Local\Temp\npm-4228-e4681199\registry.npmjs.org\azurefunctions\-\azurefu
nctions-0.0.10.tgz not in flight; adding
npm verb addTmpTarball already have metadata; skipping unpack for<EMAIL_ADDRESS>npm verb correctMkdir C:\Users\chrande\AppData\Roaming\npm-cache correctMkdir not in flight; initializing
npm verb afterAdd C:\Users\chrande\AppData\Roaming\npm-cache\azurefunctions\0.0.10\package\package.json not in flight; w
riting
npm verb correctMkdir C:\Users\chrande\AppData\Roaming\npm-cache correctMkdir not in flight; initializing
npm verb afterAdd C:\Users\chrande\AppData\Roaming\npm-cache\azurefunctions\0.0.10\package\package.json written
npm ERR! cb() never called!
C:\Users\chrande>

It doesn't look like it's happening in your code, but I've not having this happen on any other package I've tried lately.

I found the issue with run/web not working - I had a environment variable on all of my machines from a previous experiment which was being picked up and was broken. :) Works nicely now. Having a blast!

That probably does highlight some of the issues with our current model for running the host in background - we need a better debugging experience for host issues.


removes selector compactions

Removes the selector compaction table property and related SPI enum. For details see #4081

#4398 was opened to deprecate this functionality in main

I found some other places where compaction selectors are still referenced.
CompactionConfig
https://github.com/apache/accumulo/blob/a8cdaadb9f4b0fe4dcdb28a0cda4cd75d06e1dba/core/src/main/java/org/apache/accumulo/core/client/admin/CompactionConfig.java#L142-L160
ExtCEnv
https://github.com/apache/accumulo/blob/a8cdaadb9f4b0fe4dcdb28a0cda4cd75d06e1dba/server/compactor/src/main/java/org/apache/accumulo/compactor/ExtCEnv.java#L93
We could probably remove the SELECTOR encode/decode methods from the UserCompactionUtils
https://github.com/apache/accumulo/blob/a8cdaadb9f4b0fe4dcdb28a0cda4cd75d06e1dba/core/src/main/java/org/apache/accumulo/core/clientImpl/UserCompactionUtils.java#L158-L174
The largest change would be removing the selector type from the thrift code as this causes a thrift regeneration:
https://github.com/apache/accumulo/blob/a8cdaadb9f4b0fe4dcdb28a0cda4cd75d06e1dba/core/src/main/thrift/tabletserver.thrift#L119

@ddanielr  cleaned up thrift and ExtCEnv in df2ec1c.
CompactionConfig and UserCompactionUtils are ok to leave as is.  The CompactionSelector plugin could be used in two ways. The first way was a table property could be set to use it and would periodically force compactions on whatever files it selected. The second way was that a table compaction initiated via the API could optionally specify the plugin to select subsets of files per tablet.   This PR is dropping that first way of using the plugin, but the second way will still be available.  The CompactionConfig and UserCompactionUtils code referenced were related to the second way of using the plugin.

merged this so that it would be present when merging main with #4398 into elasticity.