Introduce crossbeam-channel

Introduce crate crossbeam-channel, which aims to be an upgrade over std::sync::mpsc from the standard library in pretty much all aspects: features, convenience, and performance.
Rendered
Prototype
Benchmarks

cc @jdm @SimonSapin @asajeffrey - we've chatted about this in #servo.
cc @alexcrichton @aturon @mgattozzi - talked about this at RustConf.
cc @BurntSushi - this might be a replacement for chan.
cc @insanitybit - finally! :)

In the Reddit comment thread, /u/lurebat argues that we should have explicit Select structs instead of hidden thread-local magic.

I just don't like state I can't see. Usually when I call a free function with an argument the only thing I expect to modify is that argument. But here the function doesn't even take a mutable reference and it modified a hidden state that I can't even access. I feel that it's more rustic to go with the explicit option by default, and I don't see why not have it here.

I'm sympathetic to the argument.
Here's an example of selection using hidden thread-local state:
loop {
    if let Ok(msg) = select::recv(&rx1) {
        println!("{}", msg);
        break;
    }
    if let Ok(msg) = select::recv(&rx2) {
        println!("{}", msg);
        break;
    }
    if select::timeout(Duration::from_millis(100)) {
        break;
    }
}

And this is what it would like with an explicit Select struct:
let mut sel = Select::with_timeout(Duration::from_millis(100));
loop {
    if let Ok(msg) = sel.recv(&rx1) {
        println!("{}", msg);
        break;
    }
    if let Ok(msg) = sel.recv(&rx2) {
        println!("{}", msg);
        break;
    }
    if sel.timed_out() {
        break;
    }
}

We could require the sel variable to be mut or not - it doesn't really matter because we can use Cells anyway. But perhaps requiring mut makes it clearer that there is some kind of mutable state?
Note that this way we can also make timeouts much less magical.
Any thoughts? Please upvote if you think we should go with explicit Select struct, and downvote if you prefer hidden thread-local state.

We could require the sel variable to be mut or not - it doesn't really matter because we can use Cells anyway. But perhaps requiring mut makes it clearer that there is some kind of mutable state?

One advantage to not requiring mutable is that people may want to put the Select struct into some sort of context that gets copied around.

I wish I had time to give this a proper review, but meantime, just wanted to say: thanks so much, @stjepang (and team), for what you've done for Crossbeam! I couldn't be happier.

@stjepang I'm in favor of the explicit struct approach, though it seems as though we could also offer the implicit approach as well if people are worried about verbosity, yes?
As for the need to explicitly break, is there some possible simplification to be had in association with the catch RFC? Keep in mind that I am completely unclear on the current state of that RFC (both in design and implementation), but would you find something like the following a bit nicer?
catch {
    loop {
        sel.recv(&rx1, |msg|
            println!("{}", msg);
        )?;
        sel.timed_out()?;
    }
}

I'm personally in favor of the explicit struct approach as well, however I believe that a macro, which also enforces the loop structure, could work quite well and wouldn't be too complicated, for example:
https://gist.github.com/TimNN/669d030cc99e4dcefc2b5bc6203a7019

I notice that the select algorithm as described (in the "Rendered" link) is not actually fair.  Is there a strong performance reason not to go with a fair implementation? I would expect a fair implementation to either check just one option each time through the loop (instead of about half) or to check all the options in a random order at the beginning of the loop.
The unfairness would come around if you have a select loop with many options, and a pair of them are always triggered simultaneously.  If the two that are triggered simultaneously are next to each other in the loop, then the first one will be chosen far more often than the second one.  Maybe this is unimportant, and maybe the performance cost of making it fair is not worthwhile.  But it seems worth investigating.

To make the explicit struct approach a bit neater and remove the need for explicit breaks something like this might work.
If you have a mutable reference or are constructing on the spot:
for sel in Select::with_timeout(Duration::from_millis(100)) {
    if let Ok(msg) = sel.recv(&rx1) {
        println!("{}", msg);
    }
    if let Ok(msg) = sel.recv(&rx2) {
        println!("{}", msg);
    }
}

or if you needed to store a Select in a struct behind an & reference:
let select = Select::with_timeout(Duration::from_millis(100));

for sel in select.iter() {
    if let Ok(msg) = sel.recv(&rx1) {
        println!("{}", msg);
    }
    if let Ok(msg) = sel.recv(&rx2) {
        println!("{}", msg);
    }
}

@ebarnard I like that idea.  The fewer invariants the API forces the user to manage (in this case, break on success of any rule), the better!

The for API looks nice, however has the disadvantage that you cannot return a value using break $something (unless Rust has changed recently and I didn‘t notice).

Could we allow for both the for api, and the loop/break with struct API?
Alternatively you should still be able to wrap it in a function and use return to emulate break $something.

@TimNN @gmorenz
You can return a value from a loop using a similar construction to before:
let mut select = Select::with_timeout(Duration::from_millis(100));

let msg = 'select: loop {
    // Panics if you forget to break
    let sel = select.next().unwrap()

    for rx in &receivers {
        if let Ok(msg) = sel.recv(rx) {
            break 'select msg;
        }
    }
};

@bstrie

I'm in favor of the explicit struct approach, though it seems as though we could also offer the implicit approach as well if people are worried about verbosity, yes?

Well, I'd rather choose one or the other. Having two separate, but marginally different interfaces for doing the same thing is kinda silly, isn't it? :) Let's just go with the explicit struct approach.

As for the need to explicitly break, is there some possible simplification to be had in association with the catch RFC? Keep in mind that I am completely unclear on the current state of that RFC (both in design and implementation), but would you find something like the following a bit nicer?

Interesting idea! While it does look neat, I'm worried that it just sort of pushes the problem from one place to another - now we don't have explicit breaks, but still have to write catch and ? instead. Also, the control-flow graph now loses important information. See below.
@ebarnard

To make the explicit struct approach a bit neater and remove the need for explicit breaks something like this might work.

Very nice, but this way the control-flow graph loses information - it doesn't know that the body of a successful case is executed just once anymore.
Consider the following:
let output;
let mut sel = Select::new();
loop {
    if let Ok(msg) = sel.recv(&rx1) {
        output = msg.to_string();
        break;
    }
    if let Ok(msg) = sel.recv(&rx2) {
        output = msg.to_string();
        break;
    }
}
println!("{}", output);

This code compiles because Rust knows that output will be initialized exactly once. From the control-flow-graph, it can deduce that the body of each of the ifs will be executed at most once, and that exactly one if will succeed exactly once.
If you rewrite the same example using for sel in select.iter(), it will not compile.

@stjepang
That's a shame, I hadn't thought about that. It's still possible to use the for based api with a loop if you want to return a value (see above).
However, in the case you only want to perform an operation on each received value, or there's a timeout, or some other fallible assignment the for loop presents a much nicer interface.
I suppose there's a cost to explaining both ways of using the select api though.

@nikomatsakis

One advantage to not requiring mutable is that people may want to put the Select struct into some sort of context that gets copied around. If you require mut, then they would need to use a RefCell or some such thing somewhat needlessly.

Good point! Although, I wonder why would someone attempt to store a Select anywhere else other than one line above the loop { .. }. Seems like an unusual and potentially dangerous thing to do.
Also, I'm feeling a bit uneasy about allowing to have multiple references to the same Select in two completely different places and then using them.
@TimNN

I believe that a macro, which also enforces the loop structure, could work quite well and wouldn't be too complicated, for example:

Looks pretty good! A question: would it be possible to allow optional commas between select cases? Putting an unexpected comma (or forgetting one) in macros can blow up with poor compilation error messages.
Other than that one, I don't see any quirks in the macro. Are there any I'm missing? :)
Also, we should probably also support the following syntax: send(tx, mut s) so that the returned value in Err(v) is reacquired (s = v).

Instead of just one universal Sender/Receiver pair, there could be more types for different, better-optimized kinds of channels. For example, we could have unbounded::Sender/unbounded::Receiver, or spsc::Sender/spsc::Receiver, or maybe even oneshot::Sender/oneshot::Receiver.

I like this alternative quite a bit. It eliminates the redundant monomorphizations, it eliminates the runtime dispatch on flavor, and it allows for non-Sync variants that not only achieve the same performance as std::sync::mpsc, but enforce it at compile time.
It also doesn't preclude a generic wrapper that behaves the way the current prototype does, though that would potentially make things more confusing as it would provide multiple types for the same purpose.

@rpjohnst The problem I see with having many different channel versions is that it vastly impedes the use of channels in library interfaces.  A library author either needs to create N different versions of the API, or needs to decide which variant is required by their users.  I expect the cost of the dynamic dispatch is negligible (testing would be wise), and you get a simple API that allows the users of libraries to patch them together however they like.

It would of course be possible to solve that problem by making Sender and Receiver traits, and letting libraries work with those.

I don't understand why select has to have such complicated API. I have a much simpler proposal (which might be infeasible since I have no knowledge of the internals):
let select = rx1.join(&rx2).join(&rx3).with_timeout(8);
select.wait();
if let Some(msg) = rx1.recv() { ... }
else if let Some(msg) = rx2.recv() { ... }
...
else {
    // timed out
}

@johncf That interface does not provide any fairness guarantees, so you could end up starving the second receiver if there's a steady stream on the first one and you're using the select in a loop.

@jdm Ah, then why not use select.recv(&rx1) as proposed before instead of rx1.recv_nb() ?

@TimNN's macro looks lovely, and seems far less fraught than the analogous macro from chan. Does anyone see anything immediately wrong with it? Perhaps it will end up less nice if we have to account for unforeseen edge cases. :P
@stjepang , note that when I say that I prefer the explicit Select struct, what I really mean is that I just don't like global state/TLS. :) I, and I assume many others, would likely be totally fine with the select machinery being "behind-the-scenes", especially if you're concerned about the risk of further misuse of the API.

@stjepang: I don't think there is an easy way for optional commas, but allowing an arbitrary number of commas ($(,)*) is easily possible (I've updated the gist).

@stjepang

Also, we should probably also support the following syntax: send(tx, mut s) so that the returned value in Err(v) is reacquired (s = v).

The send(tx, $ident) form of the current macro already recovers the value of $ident in case of an error (although that currently requires $ident to be mut, but that should be easy to fix: The value of $ident moves into the loop anyway and is unusable afterwards, so adding an let mut $ident = $ident before the loop should be easy enough)

Here is a refinement of the idea I proposed before, now having APIs for sending and possibly recovering failed-to-send messages.
https://gist.github.com/johncf/81778f23da91ae928e0ee7e92fda1b48

Reading through this RFC, I was quite confused by what exactly select is supposed to do. Granted, using channels is new to me, but it wasn't until I was pointed in the direction of some Unix history that I learned what select is supposed to do.
I would like to propose that select is slightly renamed to make it more clear what it is actually doing, to e.g. select_any or select_any_ready maybe (or any other name that is deemed better). I know this breaks somewhat with the precedent for this functionality (since it is named as such in Unix and Go for example), but I think there are many Rust users who are not familiar with these precedents and will hence be confused by the name (myself included). At the same time, by keeping the word "select" in the name, it is still easy to search for, for those that do know the precedent (and if "select" is kept as the first part of the name, anyone just looking to type select in their IDE will also be helped by autocomplete).
I feel this would be a very rustic improvement to make; it should still be easy for veterans to use, but welcomes newcomers at the same time, by optimizing for readability over familiarity.

@TimNN

I don't think there is an easy way for optional commas, but allowing an arbitrary number of commas ($(,)*) is easily possible (I've updated the gist).

Wonderful! Although, it's a bit surprising that the following code compiles even without braces and commas:
fn _foo(mut s: String, tx: Sender<String>, rx: &Receiver<String>) -> String {
    select! {
        disconnected() =>
            s
        // recovers `s` if unsuccessfull (currently needs `s` to be mutable,
        // but that can probably be worked around in the macro)
        send(tx, s) =>
            String::from("I did send s!")
        // Re-evaluates (and drops the result) on every execution
        send(tx, String::from("foo")) =>
            s
        recv(rx, val) =>
            val
    }
}

Can we make it an error if you omit both braces and commas?

The send(tx, $ident) form of the current macro already recovers the value of $ident in case of an error (although that currently requires $ident to be mut, but that should be easy to fix: The value of $ident moves into the loop anyway and is unusable afterwards, so adding an let mut $ident = $ident before the loop should be easy enough)

Hmm. This wouldn't work if you're trying to send a member of a struct. For example:
select! {
    send(tx, foo.message) => { ... }
}

I'd still prefer to mark explicily that ownership must be reacquired, so that send(tx, mut foo.message)  expands to:
if let Err(m) = sel.send(tx, foo.message) {
    foo.message = m;
} else {
    // ...
}

One more thing. I'm afraid that the macro obscures the fact that it is actually a loop behind the scenes. A user writing the following might assume that compute() gets called just once.
select! {
    send(tx, compute()) => println!("sent!"),
    recv(rx, val) => println!("received {}", val),
}

If compute() has side-effects, the user might be in for a bad surprise. Perhaps we should rename the macro to select_loop! or loop_select!?

@johncf

Here is a refinement of the idea I proposed before, now having APIs for sending and possibly recovering failed-to-send messages.

A few issues I can think of:

It's unfortunate that we have to mention each case twice - e.g. first as .join(&rx2) and then as if let Some(msg) = select.recv(&rx2).
We have to write else { unreachable!() } at the end to make sure we didn't forget a case, or to make code typecheck in case we're using the final value of the whole if-elseif expression.

@stjepang I have a few more concerns regarding a select! macro.

You can't break or continue a loop wrapping the select! without using a label. (Also, loop_select! sounds like a helper macro for this use-case.)

To guarantee fairness, wouldn't it be necessary to use thread-local variables to store past state? Unless select! takes a local variable given by the user to store state, as follows:
fn _foo(rx1: &Receiver<String>, rx2: &Receiver<String>) {
    let mut state = SelectState::new();
    loop {
        select! {state,
            disconnected() => {
                break;
            }
            recv(rx1, val) => {
                if val == "exit" {
                    break;
                } else {
                    System.out.println("Got {}", val);
                }
            }
            recv(rx2, val) => {
                System.out.println("Got {} from rx2", val);
            }
        }
    }
}

How can the compiler determine the liveness of a variable passed into send?
select! {
    send(tx, s) => {
        String::from("I did send s!")
    }
    recv(rx, val) => {
        val
    }
}
System.out.println("{}", s); // isn't this an error?? s might have been moved?

@johncf:

I think this is an acceptable downside. (You can statically prevent unlabeled breaks / continues inside the select macro.
The SelectState::new() stuff would be generated by the macro.
The recovery as written in your updated code works already with the macro I proposed (if s is mut, although that restriction can be lifted). [You original code example would produce a compiler error].

@stjepang:

Can we make it an error if you omit both braces and commas?

Probably, but IMO that would complicate the macro a lot for very little gain.

@TimNN

Yes, I think I remember reading that. But will the compiler be able to provide a helpful message on how to fix that?
Whatever generated by the macro would be inside the outer loop (see my code), but the state needs to be outside to outer loop for persistence.
Yes, and imagine having one more send. I just think that it is a lot of inconvenience, for an "elegant" solution (which it is only for the very basic use-case).

@stjepang: I personally like select_loop!.
Regarding the send() variants, maybe three version would work:

send($tx, $ident): The IMO most common case: $ident is made mutable and automatically recovered
send($tx, mut $($ident).*): The (nested) struct field case (works for a single variable as well): $ident is assumed to be mutable and automatically recovered
send($tx, eval $expr): An arbitrary expression, which is evaluated every time. (The eval key tries to highlight that $expr is evaluated multiple times)

@johncf

Oh, I think I see what you mean. If I understand the RFC correctly you wouldn't need past state because the "start" case of the select loop is randomly determined each time the loop is initialized.

@johncf:

The error message would look something like this (which I believe is helpful enough):

error[E0384]: re-assignment of immutable variable `_dont_use_an_unlabeled_continue_or_break_in_select_loop`
  --> src/main.rs:44:13
   |
44 |               _dont_use_an_unlabeled_continue_or_break_in_select_loop = ();
   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ re-assignment of immutable variable```

Oh I think I misunderstood your point, did you mean if there was an easy way to recover the value to a send after the select loop? If that was the question, then I don't believe there is an easy way to do that without a significantly more complex / specialized / restricted macro.

@TimNN

😕 hmm... Incorrect line numbers... I dunno YMMV.
Ah sorry, I think you're right. I only skimmed through that part earlier.
Yes, after the select-loop was what I meant. I'm not sure how common using send in select would be to comment about it though.

Reminder that potential edge-case shortcomings of the macro form aren't the end of the world, as long as it's documented how to use this library without the macro, via manually looping and breaking. If the macro will keep people from shooting themselves in the foot for 95% of use cases, then it's still a worthwhile addition.

What if we simply add a new method Select::is_done that returns true when selection is done?
Then you don't have to manually break the loop in every successful case:
let mut sel = Select::new();
while !sel.is_done() {
    if let Ok(peer) = sel.recv(rx) {
        println!("{} received a message from {}.", name, peer);
    }
    if let Ok(()) = sel.send(tx, name) {
        // Wait for someone to receive my message.
    }
}

This way you can still put a break if you want, but it's not required.

@stjepang: I believe that would have the same downside as the proposed for-loop version: the compiler could no longer guarantee that each "branch" was only taken once. (And in that case I believe the for-syntax is a bit nicer).

Thank you, everyone, for the feedback! I gave all this some thought over the last week.
Overall, it seems that the RFC is generally accepted quite well and there aren't any major blockers. I'll address some comments:

@droundy says selection is not exactly fair, which is true. I've added an item on this to the Drawbacks section. It's probably possible to make selection fairer, although it's a bit tricky to do correctly and efficiently. I'll open a separate issue on this.

@cramertj had a comment on the error type used in the recv selection case. I've introduced two new types to streamline the interface: SelectSendError<T> and SelectRecvError.

@matthieu-m had trouble understanding the selection mechanism in full detail. I've put some effort to clarify the text a bit (e.g. by explaining what wait lists are for). I know the text is not perfectly clear now either, but explaining all the subtle intricacies would require a lot more work. I'll probably put this effort into documenting the actual code instead. :)

The idea of switching from hidden thread-local state machine to explicit Select struct was universally accepted. I've addressed this in the text and in the implementation.

Some people wanted finer-grained control over Sender and Receiver by making them traits, or custom types for each channel variant (flavor). This is a reasonable idea, but I'd prefer to go with a simple interface that is basically a drop-in replacement for std::sync::mpsc, at least for now.

There were proposals for alternative selection interfaces. Unfortunately, I don't think any of those were tangibly better than the current one. All the proposals would fix some issues in the current mechanism, but then introduce new problems along the way.

A lot of people think selection has brittle interface (it's easy to accidentally use it incorrectly). I can agree with that. The best solution would be to introduce a macro for more convenient and foolproof selection. Thanks to @TimNN for a very promising prototype! I'm definitely onboard for a selection macro and will open an issue so we can discuss this further. A new RFC just for the macro may follow up later.

It's unfortunate that incorrect use of selection can lead to deadlocks and similar weirdness. We should definitely add some runtime checks to make sure that the same set of selection cases is visited in the same order in each iteration of the loop. Will open an issue for that.

Some bikeshedding... Channels are constructed using functions named bounded and unbounded, which should be pretty self-explanatory. I intentionally chose those names instead of channel and sync_channel (as in the standard library) to avoid confusion, especially because Go calls zero-sized channels synchronous and bounded channels asynchronous (while Rust calls those synchronous :D). How does everyone feel about that? A possible alternative would be to have just a single function new(cap: Option<usize>).
Finally, I'd like to push forward and publish version 0.1.0 now so that everyone can start playing with the channel. The interface as presented in this RFC will not be set in stone, so if we figure out how to improve it down the line, we'll definitely do it! But let's get some mileage first. How does that sound, @jeehoonkang?

in order to serve as many people as possible, how about shipping @TimNN's macro in 0.1.0?  From the discussions so far, I couldn't see any drawback in doing so.

I feel "bounded/unbounded" are better names than "sync/async"; they explain exactly what they do.  Also, I don't see much benefit of new() at this moment.  Let's hear experience from users after releasing it.

Even though channel's code is not reviewed at all, I'm quite sure that it's well-written 😃, and at the very least it's tested and its interface is reviewed.  Also, it seems users are waiting for a new Crossbeam release a lot!  Let's review and enhance it after releasing it.

Thanks for this great job, let's move forward!

in order to serve as many people as possible, how about shipping @TimNN's macro in 0.1.0 From the discussions so far, I couldn't see any drawback in doing so.

I can send a PR with the initial macro to the prototype repo, which should also allow us to better discuss the implementation details there.

Regarding the fairness, I just had the following idea (I haven't properly thought it through yet, but wanted to write it down):
This approach is probably a bit more expensive but should still be manageable: The core idea is to change the "two half" iteration to something different, so that neighboring operations are not necessarily directly next to each other.
This can be achieved by, instead of choosing a split point, choosing a skip count: Chose a skip count X, then skip X operations, perform one operation, skip X operations, perform one operation and repeat until every operation has been performed once (but see caveats / details below).
Example:
Consider six operations A - F. With a split point the "check" order would be something like C.D.E.F.A.B for a split point of 2.
For skip counts between 0 - 5 the following orders are possible: A.B.C.D.E.F, B.D.F.A.C.E, C.F.B.E.A.D, D.A.E.B.F.C, E.C.A.F.D.B and F.E.D.C.B.A.
Caveats / Details:
Assume N operations in the loop. To guarantee that we visit all operations, we need to find a prime P > N and assume there are actually P "operations" in the loop. We also choose a random skip count X (0 <= X < N). To visit all elements in the loop we then do the following:

Start at position i = 0
Skip X operations (i = (i + X) % P)
If the current operation does not actually exist (i >= N) goto 1.
Visit the operation at position i
If we have not yet visited N operations, goto 1.

Since P is prime and X < P, we are guaranteed to visit every position once before repeating.
Fairness: If I remember my probability theory lessons correctly this system should guarantee that the probability that a specific operation B is visited directly after an operation A should be approximately equally likely for all possible operations B. This should provide some fairly strong fairness guarantees.
Disadvantages:
This method is less performant than the "split point" algorithm:

It requires finding a suitable prime P, although that should be trivial for any reasonable value of N.
For large values of X the loop may need to be executed almost N times instead of only twice. This may be especially problematic in the face of expensive send value computations / moves due to send value recovery.

And now I've spent way too long writing this down and it is way too late, and I just realized that this turns the whole operation essentially from O(n) to O(n^2), which is probably too slow for a default but maybe works as an "extra-fair" select. Anyway, I'll think about this some more tomorrow. Comments / Feedback are very welcome.

I'm in favor of bounded/unbounded.

@stjepang Thanks for your thoughtful response and thorough summary.  I think your response to the unfairness issue was particularly fair.  (Apologies for the pun.)
On the bikeshedding, I agree that bounded and unbounded are way better than sync/async, but wonder whether even better names are possible.  In particular, I wonder whether 3 names could be more instructive, even if one name is a special case for bounded(0).  To my mind a zero-length bounded channel is a distinctively different thing (in use) than a channel with a finite-length buffer, and I wonder whether there is a more descriptive name for it.  The zero-length buffer really means that the receiver and sender are synchronized.  In terms of reasoning (and deadlocks) this is very different behavior from a channel with either finite (but non-zero) or infinite buffer...
What about blocking (zero-length buffer), buffered, and nonblocking? That avoids the "sync" syllable which is backwards between go and standard rust, and focuses instead on whether the channel will block.  Of the three names, buffered doesn't quite match the others, which I don't like.  But a finite buffer will sometimes wait for input (or a reader) and will sometimes not block.

@TimNN I think a simpler version of your algorithm would simply be to randomly choose one operation to attempt each time through the loop.  It is still O(N^2), but is easier to reason about than the skipping version.  The prefactor on the O(N^2) shouldn't be too bad if no extra work is done in the loop, an you really want no extra work to be done in the loop, or the implementation leaks.
Also O(N^2) isn't too bad if N is small, and when N is large is precisely when the non-fairness gets large with the current implementation, so users might be likely to value it more when it is more expensive.  That said, I think the current plan to document the unfairness and postpone any idea of fixing it is good.

That said, I think the current plan to document the unfairness and postpone any idea of fixing it is good.

I agree!

I think a simpler version of your algorithm would simply be to randomly choose one operation to attempt each time through the loop.

Ah, now I understand your earlier comment. I don't think that could easily work, consider this because you aren't guaranteed to visit all operations once:

No operation is ready, the thread parks itself.
The thread is unparked
The thread randomly visits N operations
The operation that unparked the thread is not visited
<I can imagine multiple things that happen now, but overall I would consider this situation bad>

I think adding the following API to Select would make using it (with the macro) even safer for negligible costs:

.enable_extra_checks(): Called before the loop and enables extra checks (= the one below)
.register_loop_end(): Called at the very end of the loop

This will allow checking if the same end of a specific channel was used more than once, which means that the macro can enforce / catch violations of all three "important rules one must follow in order to use selection correctly" listed in the RFC either at run- or compile-time.

Another thought: If this can easily be supported by the implementation it might be nice to have a Select::send version which takes a closure instead of a value: This version would attempt to reserve a spot in the channel and only if that is successful would it evaluate the closure.

@TimNN You are right about my idea, it would only work if the thread never parked, which would be terribly inefficient.  Perhaps just creating an array with length of the number of options, and then shuffling it to determine the order of attempts? The shuffling is an O(N) operation, and then we'd have to run through the loop O(N) times, so it's still an O(N^2) approach, I think.
Regarding your closure suggestion, that would seem to make the code far easier to use without side effects or repeated computation.

To everyone interested in the select_loop! macro: follow the discussion in this pull request.

@droundy @TimNN  Regarding fairness, we could do the following.
In the first iteration of the loop, while counting cases we also check which cases are ready by calling internal methods .can_send() and .can_recv(). These methods check whether there's a waiting receiver/sender on the other side of the channel, respectively.
Typically we select over no more than a dozen or so cases, so we can remember which cases are ready by marking a bit for each ready case in a u32 bitmask. Then we choose a random number between 0 and bitmask.count_ones() (let's call it R) and set start to the index of the Rth bit in the bitmask.
There is some performance cost associated with checking which cases are ready (I believe the cost is around 10%), but it's probably not too bad.
@droundy

What about blocking (zero-length buffer), buffered, and nonblocking?

For me, names blocking/nonblocking are not much more understandable than synchronous/asynchronous. :) I prefer to differentiate channels by how many messages they can hold: are they infinite, do they have a bounded buffer, or are they zero-sized. The last kind is very special, that is true. It is sometimes also called a rendezvous channel.
It might be nice to have a dedicated constructor for zero-sized channels, but I'm afraid at the same time it might also make constructors more complicated than is necessary.
Note that there is already some precedent for constructors similar to bounded(cap). For example, in Go you can construct bounded channels with make(chan int, 0) and make(chan int, 50), while in Rust you can do sync_channel(0) and sync_channel(50).

I'm merging this RFC and publishing the first version.
New repository: https://github.com/crossbeam-rs/crossbeam-channel
Documentation: https://docs.rs/crossbeam-channel
You can add crossbeam-channel = "0.1.0" to your Cargo.toml and try it out!
extern crate crossbeam_channel;

use crossbeam_channel::unbounded;

fn main() {
    let (tx, rx) = unbounded();
    tx.send("Hello").unwrap();
    tx.send("World").unwrap();
    drop(tx);

    for msg in rx {
        print!("{} ", msg);
    }
    println!();
}

I decided to include select_loop! macro for easier selection. Thanks again to @TimNN for implementing it! As is often the case with macros, there are still a few warts in it and you can run into weird compilation errors, but I believe it's much less likely than with select!.
Let me know if you have any feedback or comments. I'm especially curious:

How difficult is it to switch from std::sync::mpsc to crossbeam-epoch?
Did you notice any difference in performance?
How does the select_loop! macro feel?
Did you notice weird compilation errors produced by select_loop!? Any examples?
If you notice any bugs, please open an issue in the repo. Thanks!

Finally, the remaining problems can be tracked in dedicated issues:

Selection fairness
Runtime checks for selection

Just one more bikesheddy question. :)
I'd like to split the disconnected() case into two: all_disconnected() (fired when all selected channels are disconnected) and any_disconnected() (fired when any selected channel is disconnected). Crate ipc-channel (used in Servo) needs this feature.
Do you think names all_disconnected and any_disconnected are adequate? Any better suggestions?


Internal assert on corrupted filesystem caused boot loop

LFS: v1.3 9ee112a7cbdbf15a6aee931527f87f587ca523e5
Also reproduced with LFS v1.7.2
I have a filesystem that became corrupt during a power cycle, I believe. When the device next booted it went into a boot loop due to an internal assert:
Assertion failed: (block < lfs->cfg->block_count), function lfs_cache_read, file littlefs/lfs.c, line 18.
The assert is this one:
LFS_ASSERT(block < lfs->cfg->block_count);

The corruption seems to have resulted in a stored block number of 1001106, when the disk is only 1024 blocks long.
I can supply the filesystem image privately if that's helpful. It contains proprietary information, so I am not able to post it publicly. I could probably post just the bad block publicly.
I'm not sure how the corruption happened in the first place, but my bigger concern is that lfs_cache_read asserts in this situation instead of returning an error code. If it returned an error code I could capture that and try to reformat the filesystem.
I have disabled the asserts and then I am able to get an error code and continue by reformatting, instead of crashing. The function tries to read that high block number, the flash subsystem returns an error and the error bubbles up.
So, I have a couple questions:

Are the asserts intended to be used in production, or just debugging?
If the asserts are disabled, should I generally expect the code not to crash and return error codes, or do the asserts protect against possible crashes on bad data?

Thanks,
Jason

Hi @vonnieda, sorry for such a late response. Hopefully it's still useful to have your questions answered.

Are the asserts intended to be used in production, or just debugging?

The asserts in littlefs are used to indicate a situation that should not happen. littlefs isn't programmed to behave itself if an assert fails, so the assert provides a last-minute safe-gaurd to prevent it from corrupting itself.
The asserts should not normally trigger, however there are enough bugs in littlefs still that seeing an assert failure is not uncommon. I'm working on improving this here: https://github.com/ARMmbed/littlefs/pull/372, but it's built on the v2 branch.
I would suggest keeping the asserts on if you can afford the code-space in production, since there's no other reason to disable them.
One big thing that's improved in https://github.com/ARMmbed/littlefs/pull/372 is how littlefs responds to corrupted disks. Currently, littlefs asserts on a corrupted disk, but in https://github.com/ARMmbed/littlefs/pull/372 has changed these asserts to return errors, giving users a chance to recover (the block < block_count assert falls into this category).
Unfortunately, there aren't any plans to backport https://github.com/ARMmbed/littlefs/pull/372 to v1.

If the asserts are disabled, should I generally expect the code not to crash and return error codes, or do the asserts protect against possible crashes on bad data?

It's the second option. If an assert fails, you can't expect littlefs to work afterwards.
However, one thing you can do is replace the assert with a condition that returns an error:
- LFS_ASSERT(block < lfs->cfg->block_count);
+ if (block < lfs->cfg->block_count) {
+     return LFS_ERR_CORRUPT;
+ }

This should work in more cases and cause littlefs to propogate the error upwards.
It's important to note you still can't expect littlefs to work in this situation.
This is ok:
int err = lfs_file_open(&lfs, &file, "path", LFS_O_RDONLY);
if (err == LFS_ERR_CORRUPT) {
    assert(lfs_unmount(&lfs) == 0);
    assert(lfs_format(&lfs, &cfg) == 0);
    assert(lfs_mount(&lfs, &cfg) == 0);
    assert(lfs_file_open(&lfs, &file, "path", LFS_O_RDONLY) == 0);
}

This is not a good idea and will likely break later in surprising ways:
int err = lfs_file_open(&lfs, &file, "path", LFS_O_RDONLY);
if (err == LFS_ERR_CORRUPT) {
    assert(lfs_file_open(&lfs, &file, "other_path", LFS_O_RDONLY) == 0);
}

If you have threads, another option is killing the thread inside the assert and restarting the "process".

Hi @vonnieda, sorry for such a late response. Hopefully it's still useful to have your questions answered.

Are the asserts intended to be used in production, or just debugging?

The asserts in littlefs are used to indicate a situation that should not happen. littlefs isn't programmed to behave itself if an assert fails, so the assert provides a last-minute safe-gaurd to prevent it from corrupting itself.
The asserts should not normally trigger, however there are enough bugs in littlefs still that seeing an assert failure is not uncommon. I'm working on improving this here: #372, but it's built on the v2 branch.
I would suggest keeping the asserts on if you can afford the code-space in production, since there's no other reason to disable them.

Thanks for the response @geky!
I can afford the code space, but the issue is that this causes a boot loop that I can't predict. If the filesystem has become corrupt, the only way to know is to try to use it and then it crashes due to the assert.

One big thing that's improved in #372 is how littlefs responds to corrupted disks. Currently, littlefs asserts on a corrupted disk, but in #372 has changed these asserts to return errors, giving users a chance to recover (the block < block_count assert falls into this category).
Unfortunately, there aren't any plans to backport #372 to v1.

Okay, thanks. I'll look into upgrading to 2.

If the asserts are disabled, should I generally expect the code not to crash and return error codes, or do the asserts protect against possible crashes on bad data?

It's the second option. If an assert fails, you can't expect littlefs to work afterwards.
However, one thing you can do is replace the assert with a condition that returns an error:
- LFS_ASSERT(block < lfs->cfg->block_count);
+ if (block < lfs->cfg->block_count) {
+     return LFS_ERR_CORRUPT;
+ }

This should work in more cases and cause littlefs to propogate the error upwards.
It's important to note you still can't expect littlefs to work in this situation.
This is ok:
int err = lfs_file_open(&lfs, &file, "path", LFS_O_RDONLY);
if (err == LFS_ERR_CORRUPT) {
    assert(lfs_unmount(&lfs) == 0);
    assert(lfs_format(&lfs, &cfg) == 0);
    assert(lfs_mount(&lfs, &cfg) == 0);
    assert(lfs_file_open(&lfs, &file, "path", LFS_O_RDONLY) == 0);
}

This is similar to how I've fixed it for now. In my case, the only assert I've ever seen has been block < lfs->cfg->block_count and since that is handled by my block device read() I just disabled asserts and let it through. So now, during boot I run an lfs_traverse and if I get any errors during that I unmount, format, mount, and traverse again.
Given that that's the only assert I've seen, it would probably be safer to modify the code to return the error as you've mentioned, but I don't want to risk another assert causing a boot loop.

This is not a good idea and will likely break later in surprising ways:
int err = lfs_file_open(&lfs, &file, "path", LFS_O_RDONLY);
if (err == LFS_ERR_CORRUPT) {
    assert(lfs_file_open(&lfs, &file, "other_path", LFS_O_RDONLY) == 0);
}

If you have threads, another option is killing the thread inside the assert and restarting the "process".

If I were to turn asserts back on, do you have any suggestions for a robust check I could perform? Or would you recommend going straight to v2?
Thanks,
Jason

If I were to turn asserts back on, do you have any suggestions for a robust check I could perform? Or would you recommend going straight to v2?

If you're able to, I would recommend adopting v2 (once https://github.com/ARMmbed/littlefs/pull/372 lands).
Unfortunately, the only check I have in MCU-friendly code is littlefs's mount, which as you note doesn't fail gracefully (until https://github.com/ARMmbed/littlefs/pull/372).

Thanks @geky - appreciate the response. I'll look towards migrating to v2.


Add a CONTRIBUTING.md

Describes the process of opening an issue, signing the CLA and our target response rate.
Borrowed liberally from our exisitng bug update SLO and other Google
contributing guides:
https://github.com/GoogleCloudPlatform/google-cloud-python/blob/master/CONTRIBUTING.rst
https://github.com/GoogleCloudPlatform/google-cloud-common/blob/master/contributing/readme.md
https://github.com/GoogleCloudPlatform/google-cloud-go/blob/master/CONTRIBUTING.md

You can check out what it looks like in my fork: https://github.com/hfwang/cloudsql-proxy/blob/e2023488962642a2de00a15be536c0b058fc673d/CONTRIBUTING.md


fix(type) : Remove extra $ in responses types

Hello !
Thank you very much for this library 🙏 ! At Pennylane, we use it a lot to improve the communication between our frontend & backend engineers. 🎉
Since we updated the library's version, in the client.d.ts file, the responses's types have been prefixed with a " $ ".
I guess that is because the "$" is now added by the dts-generator library ?
How to reproduce :
Run ./typegen ../__tests__/resources/example-pet-api.openapi.yml and have a look at the generated ts file. You will see that each response type is something like OperationResponse<Paths.OperationId.Responses.$$200> .
I was wondering if you will be ok to remove the extra "$".

I didn’t see any contributing guides, so let me know if I’ve done something wrong.
Thanks,

Thank you so much @gterral !


Add request header hostname to log

Meetesh's change to add the request header hostname to the log.

@allanbomsft,
Thanks for your contribution as a Microsoft full-time employee or intern. You do not need to sign a CLA.
Thanks,
Microsoft Pull Request Bot


“Formally Intune”

[Enter feedback here]
Why does this article state Endpoint Manager is “formally Intune”?
The Microsoft docs for Endpoint Manager clearly state Intune is a feature of Endpoint Manager. Endpoint Manager is not “formally Intune”, it’s a suite of solutions that include Intune.
Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

ID: 673970ca-2f79-a288-978c-ceb4845c5062
Version Independent ID: 2a58449f-b0d4-bf17-1209-d7b8ec0481b6
Content: Turn on network protection
Content Source: microsoft-365/security/defender-endpoint/enable-network-protection.md
Product: m365-security
Technology: mde
GitHub Login: @denisebmsft
Microsoft Alias: deniseb

@DarrenBennett Thank you for your feedback. We have made changes to the document via PR#https://github.com/MicrosoftDocs/microsoft-365-docs/pull/6805
Thanks
Sri

@msbemba Thanks for the update of the document and for updating me.

@msbemba Thank you very much for the contribution and updating the documentation with PR. @DarrenBennett Hope this update is helpful for you. Thanks for taking out some time to open the issue. Appreciate and encourage you to do the same in future also.


docs(databases): add influxdb to database drivers list

SUMMARY
Since the development of the flightsql-dbapi pypi package, users can now use this to connect InfluxDB 3.0 to superset. We'd like to advertise this on your database driver page.
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
AFTER:

TESTING INSTRUCTIONS
run the docs locally to confirm no breaking changes
ADDITIONAL INFORMATION

[ ] Has associated issue:
[ ] Required feature flags:
[ ] Changes UI
[ ] Includes DB Migration (follow approval process in SIP-59)

[ ] Migration is atomic, supports rollback & is backwards-compatible
[ ] Confirm DB migration upgrade and downgrade tested
[ ] Runtime estimates and downtime expectations provided

[ ] Introduces new feature or API
[ ] Removes existing feature or API

This is great to hear @helenosheaa ! One question, does this dialect support any kind of time grain functionality (typically DATE_TRUNC or similar)? I would assume this is a fairly important feature when doing analytics on a timeseries database. If so, we would need to add a db engine spec to support it. Let me know if you need help with it.

@villebro thanks for the quick feedback so SQL Alchemy which is the dialect does support date_trunc, however i don't know if the pypi package has been setup to translate that to time grains.. or is that what the db engine spec does? screenshot of me running it against docker without any time grains:

If so I can have a go at creating one, I see the other examples look straightforward

@villebro i'm not sure if this engine spec is needed/correct if you can take a look
our engine/dialect definition is defined here
but i wasn't sure if it should just be referring to it as influxdb3

I think this is good to be approved correct?


Adding TTS via Options.PerTriggerOptions

Hi,
Thanks for your hard work. I was wondering if it is not possible to add TTS to an existing Trigger via the User raidboss : Options.PerTriggerOptions ?
It seems I can enable and disable the various options but not add TTS if it doesn't already exist within the trigger.  See my example below:
Options.PerTriggerOptions = {
'General Provoke': {
SpeechAlert: true,
SoundAlert: true,
TextAlert: false,
tts: 'Provoke',
},
}
Thanks for your help.

You're wanting to be able to override or add the tts to particular triggers? (Are there ones you find particularly annoying?)
This should be pretty easy for me to add.  I'll try to take a look this weekend.

Quick alternative would be to copypaste the trigger into your user triggers and disable the one you copied from. Then you can edit it to taste.

Hi quis,
I just wanted the "general provoke" to have a TTS too. Not annoying at all.
Dana, yes, I work around it with what you suggested. Disabled "General Provoke" and created a new "Nox Provoke".  There is however a problem with this, the js file in the user folder can't take the same regex format as the ones in the "Triggers" folder. Guessing it's to do with special characters etc. Like if you copy paste the exact same "General Provoke" for instance, the whole user file breaks. It's something to do with the detecting player name regex but haven't found it yet.
Thanks

Also , no rush. Whenever you can take a look.  There is one other thing that I would really like to do and thought you already had was detecting certain regex actions by role. I thought the following line did that:
condition: function(data) { return data.role == 'tank' },
But doesn't seem to work. I was writing something to detect and TTS Tank Deaths. I workaround it by using the names of our static tanks for now. Like:
regex: /Mickey Mouse is defeated by/,
Thanks again.

Can you paste your user file's content when it's not working, with the condition, to help debug?

Sure. This is working file where I had to strip out some of the regex:
Options.AlertsEnabled = true
Options.TextAlertsEnabled = true
Options.SoundAlertsEnabled = true
Options.SpokenAlertsEnabled = true
Options.ShowTimerBarsAtSeconds = 30
Options.KeepExpiredTimerBarsForSeconds = 0.7
Options.BarExpiresSoonSeconds = 8
Options.MaxNumberOfTimerBars = 6
Options.InfoSound = '../../resources/sounds/freesound/percussion_hit.ogg'
Options.AlertSound = '../../resources/sounds/BigWigs/Alert.ogg'
Options.AlarmSound = '../../resources/sounds/BigWigs/Alarm.ogg'
Options.LongSound = '../../resources/sounds/BigWigs/Long.ogg'
Options.InfoSoundVolume = 2
Options.AlertSoundVolume = 2
Options.AlarmSoundVolume = 2
Options.LongSoundVolume = 2
Options.DisabledTriggers = {
'General Ready check': true,
'General Provoke': true,
}
Options.Triggers = [
{
zoneRegex: /.*/,
triggers: [
  {
    regex: /:You are defeated by/,
    alarmText: 'YOU DIED',
  },
  {
    regex: /You blow a kiss/,
    sound: '../../resources/sounds/PowerAuras/bigkiss.ogg',
    volume: 1,
  },
  {
  id: 'Nox Provoke',
  regex: /:1D6D:Provoke:/,
  condition: function(data) { return data.role == 'tank' },
  infoText: 'Provoked',
  tts: 'Provoked',
  },
  {
    id: 'Nox Passage',
    regex: /You gain the effect of Passage of Arms/,
    infoText: 'Passage of Arms',
    tts: 'Passage Up',
  },
  {
    id: 'Nox Veil',
    regex: /You gain the effect of Divine Veil/,
    infoText: 'Divine Veil',
    tts: 'Divine Veil Up',
  },
  {
  id: 'Tank Death',
  regex: /Blah Blah is defeated by/,
  condition: function(data) { return data.role == 'tank' },
  alarmText: 'Tank Death',
  tts: 'Tank Death',
  },
],

},
]
Options.PerTriggerOptions = {
}

Not working file with the "General Provoke" format replacing mine:
Options.AlertsEnabled = true
Options.TextAlertsEnabled = true
Options.SoundAlertsEnabled = true
Options.SpokenAlertsEnabled = true
Options.ShowTimerBarsAtSeconds = 30
Options.KeepExpiredTimerBarsForSeconds = 0.7
Options.BarExpiresSoonSeconds = 8
Options.MaxNumberOfTimerBars = 6
Options.InfoSound = '../../resources/sounds/freesound/percussion_hit.ogg'
Options.AlertSound = '../../resources/sounds/BigWigs/Alert.ogg'
Options.AlarmSound = '../../resources/sounds/BigWigs/Alarm.ogg'
Options.LongSound = '../../resources/sounds/BigWigs/Long.ogg'
Options.InfoSoundVolume = 2
Options.AlertSoundVolume = 2
Options.AlarmSoundVolume = 2
Options.LongSoundVolume = 2
Options.DisabledTriggers = {
'General Ready check': true,
'General Provoke': true,
}
Options.Triggers = [
{
zoneRegex: /.*/,
triggers: [
  {
    regex: /:You are defeated by/,
    alarmText: 'YOU DIED',
  },
  {
    regex: /You blow a kiss/,
    sound: '../../resources/sounds/PowerAuras/bigkiss.ogg',
    volume: 1,
  },
  {
  id: 'Nox Provoke',
  regex: /:(\y{Name}):1D6D:Provoke:/,
  condition: function(data) { return data.role == 'tank' },
  infoText: function(data, matches) {
    return 'Provoke: ' + matches[1];
  },
  },
  {
    id: 'Nox Passage',
    regex: /You gain the effect of Passage of Arms/,
    infoText: 'Passage of Arms',
    tts: 'Passage Up',
  },
  {
    id: 'Nox Veil',
    regex: /You gain the effect of Divine Veil/,
    infoText: 'Divine Veil',
    tts: 'Divine Veil Up',
  },
  {
  id: 'Tank Death',
  regex: /Blah Blah is defeated by/,
  condition: function(data) { return data.role == 'tank' },
  alarmText: 'Tank Death',
  tts: 'Tank Death',
  },
],

},
]
Options.PerTriggerOptions = {
}

There's a  TTSApp that comes packaged with some Neospeech voices (Kate16 specifically I have) and a few others that allows you to create tts wav files. The easiest thing to do I would think, simply to replace bigkiss.ogg with the .wav. Assuming it works with .wav. You can always convert to OGG.
Here's an example
You have the added bonus of using different voices, if you want to as well. Just a suggestion.

There is one other thing that I would really like to do and thought you already had was detecting certain regex actions by role. I thought the following line did that:
condition: function(data) { return data.role == 'tank' },

For what it's worth, data.role is your role.
I think the only way you would be able to do this would be a complicated set of triggers, where you'd have some triggers that would detect tank skills (like heavy swing), and then set a variable on data with the names of those tanks, and then in some other trigger you could then check if the person's name who died was somebody who had previously used a tank skill.  Probably the easiest is just to do it by name of the person in your static.

Hi,
That explains it then. Should have checked what it does properly. It's no big deal really, works well when regexing by player name. I will keep it like that. No need to overcomplicate it.
The tts thing is also no massive issue. Thanks for suggestion XDemon but I think I will stick to just rewriting my own custom one for now that can use TTS. I am likely to want to create more and don't really want to keep creating new sound files.
Nox

@noxaeternus If I added tts to the provoke triggers, would you want:
(1) Provoke + person's name
(2) Just 'provoke'
(3) Either of the above, but only when it's somebody else (and not you) doing the provoke.
I don't want to make tts be too noisy, so was just curious what you would prefer as somebody who wanted this themselves.

1 would be perfect as it would register my own provoke too. But either is fine.  You are right, you don't want too much noise but it would be nice to track.


Made less files searchable through dev tools

Added sourceURL to make less files searchable through dev tools.

Thanks!


4.0.0 multi router

Multiple router is very useful for some project ,especially hybrid app when native code want to start different RN component at different  page but using same RCTBridge.
For now(4.0.0-beta.24), multiple router in RNRF is not supported yet, so I wrote some code try to enhance it, and I also mentioned that other guys could need this feature like  #2274
So, this PR is sent. hopefully helpful.
I also wrote a demo to demonstrate how to  use multiple router in hybrid app ,check it out
https://github.com/brrr/example_RNFR_MULTI_ROUTER

Sorry for the delay, we were working on upgrade RNRF to latest React Navigation (2.x). If you still want to have this functionality, please apply new PR for new version (beta.40)


Kusto extension for ADS

This change adds a Kusto extension for ADS. Mostly the code is a replica of the mssql extension. The interesting parts are:

The package.json definition
Some kusto language definitions
Kusto icon files from the design team

There's a lot of changes, so I may have missed it.  Can you confirm that the 'kusto' extension has been added to the externalExtensions array in build/lib/extensions.ts?  This is necessary so the build will properly create a VSIX for the extension vs. bundling into the main layout.

There's a ton of duplicate code here with mssql extension.  It's probably worthwhile at some point to refactor out shared code into common codebase so we can keep bug fixes in sync.

There's a lot of changes, so I may have missed it. Can you confirm that the 'kusto' extension has been added to the externalExtensions array in build/lib/extensions.ts? This is necessary so the build will properly create a VSIX for the extension vs. bundling into the main layout.

Thanks for pointing this out. Added.

Coverage decreased (-0.07%) to 38.691% when pulling 633e253a5c184db412d7d8542b4ea5ee9071ceab on PR/KustoExtension into 8cf82c1f8b2c952e19ad8d04245b537c30034ce3 on main.

There are some security failures in the Ad Hoc build - looks like some of the libraries are out of date?

I have updated the libraries, so its not failing anymore.

The adhoc failure is unrelated to this PR so feel free to merge.


Error on assosiated view

I got this error when navigating on an associated view.
Opening an issue so I don't forget.

Hi @Konstantin-Enev ,
I remember trying to figure it out but its more complicated than I thought.
It seems that I cannot get the information needed from the context, the information surfaced by these cell renderers is very limited.
I know where it crashes exactly. I'll try to give it another shot or at least fail more gracefully so the grid could be displayed and the customizer skipped.


GZip shouldn't prompt the user to overwrite an existing file

If you GZip.open an existing file in "wb" mode, it prompts you at the console if you want to overwrite it, regardless of isinteractive().
shell> touch random.gz

julia> using GZip; GZip.open("random.gz", "wb")
random already exists -- do you wish to overwrite (y or n)?

I don't think we should do this. Instead we should follow the Linux Standard Base Specification, which says:

The mode argument is based on that of fopen()

i.e. it should follow C convention to silently truncate to zero length.

Oh wait nevermind this was a completely different problem in my script. Sorry.


Thread safety

If I call this function from multiple threads at the same time (it's currently using 8 worker threads):
#include "FastNoise/FastNoise.h"

void Generate2dNoise(
        int xOffset, int yOffset, int xSize, int ySize, int seed, int octaves, float frequency, float* output
) {
    auto fnSimplex = FastNoise::New<FastNoise::OpenSimplex2>();
    auto fnFractal = FastNoise::New<FastNoise::FractalFBm>();

    fnFractal->SetSource(fnSimplex);
    fnFractal->SetOctaveCount(octaves);
    fnFractal->GenUniformGrid2D(
            output, xOffset, yOffset, xSize, ySize, frequency, seed
    );
}

I get random segfaults every once in awhile (it seems to happen pretty early on, or not at all)
Relevant part of the callstack:

Using a global mutex around that function solves the issue, so it seems to be something concurrency related.
(Is there any obvious issue with how I'm using the library / is FastNoise2 actually meant to be threadsafe?)

There was a bug found in the thread safety of SmartNodes, the latest release (0.9.5) contains the fix for it

There was a bug found in the thread safety of SmartNodes, the latest release (0.9.5) contains the fix for it

This happens with 0.9.5-alpha (from the release download)

From your code above it looks like you are creating a new SmartNode per function call, ie no cross-thread access for a given node, is that true? or is the code above simplified?

That's the function being called each time (it's just copy pasted directly.) There's an FFI boundary to get to that function, which I should have mentioned in the original ticket (sorry, just forgot to include it.) No cross thread access for a given node, or at least, there shouldn't be afaict.
The FFI code is basically this right now:
    let mut result =
        Vec::with_capacity(x_size as usize * y_size as usize);
    result.resize(result.capacity(), 0.0);
    let _lock = MUTEX.lock();
    unsafe {
        ffi::Generate2dNoise(
            x_offset.into(),
            y_offset.into(),
            x_size.into(),
            y_size.into(),
            seed.into(),
            octaves.into(),
            frequency,
            result.as_mut_ptr(),
        );
    }
    return result;

(If this is only showing up for me, I can try to repro it in just C++ later)

Is your xSize * ySize < 8 it could be the same bug as #89 I'm working on a fix for it now

They're all 32x32 (so xSize * ySize = 1024)
I'll see if I can come up with a better set of repro steps, but it also hasn't happened again today. (Maybe I missed clearing out some build artifacts from the old version? Or could just be some weird thing affecting a race condition? It did seem to happen more often when the rest of the app was running at higher framerates, for whatever reason)

Can you see what line of code it is crashing on?

It's hard to pinpoint exactly right now because it's mangled from the linker / can only get disassembly, but it looks like it's somewhere in this:
GenUniformGrid2D or here
and then here: (from the assembly it seems like it's when the function returns? which seems weird)
OpenSimplex2 generator

Could you show the assembly where it crashes? Can you get the crash on a debug build for more info?

Yep! I'll see if I can setup the debug build etc, if I can't get that working I'll try setting up a purely C++ repro using the same compiler tooling etc later (probably won't have time this week for that one tho)

Here's the disassembly! haven't seen it crash with a debug build yet, though: https://gist.github.com/jihiggins/164ed62dd843e59c736f5ba3b208d1cf#file-disassembly-asm-L48

Thanks. In FastNoise_Config.h could you change #define FASTNOISE_USE_SHARED_PTR false to true will help determine if it's a SmartNode issue or something else

That's set, got a new crash from an assertion in debug mode.
First assertion:
https://github.com/Auburn/FastNoise2/blob/v0.9.5-alpha/include/FastNoise/Generators/Generator.h#L141
https://github.com/Auburn/FastNoise2/blob/v0.9.5-alpha/include/FastNoise/Generators/Fractal.h#L10
    fnFractal->SetSource(fnSimplex); (from the first post)
If I continue, next assert is:
https://github.com/Auburn/FastNoise2/blob/v0.9.5-alpha/include/FastNoise/Generators/Generator.inl#L42
https://github.com/Auburn/FastNoise2/blob/v0.9.5-alpha/include/FastNoise/Generators/Generator.h#L143
https://github.com/Auburn/FastNoise2/blob/v0.9.5-alpha/include/FastNoise/Generators/Fractal.h#L10
    fnFractal->SetSource(fnSimplex); (from the first post)
Then:

https://github.com/Auburn/FastNoise2/blob/v0.9.5-alpha/include/FastNoise/Generators/Generator.inl#L61
https://github.com/Auburn/FastNoise2/blob/v0.9.5-alpha/include/FastNoise/Generators/Fractal.inl#L24
https://github.com/Auburn/FastNoise2/blob/v0.9.5-alpha/include/FastNoise/Generators/Fractal.inl#L15
https://github.com/Auburn/FastNoise2/blob/v0.9.5-alpha/include/FastNoise/Generators/Generator.inl#L102
And finally, access violation here:

https://github.com/Auburn/FastNoise2/blob/v0.9.5-alpha/include/FastNoise/Generators/Generator.inl#L42
https://github.com/Auburn/FastNoise2/blob/v0.9.5-alpha/include/FastNoise/Generators/Fractal.inl#L24
https://github.com/Auburn/FastNoise2/blob/v0.9.5-alpha/include/FastNoise/Generators/Fractal.inl#L15
https://github.com/Auburn/FastNoise2/blob/v0.9.5-alpha/include/FastNoise/Generators/Generator.inl#L102
    fnFractal->GenUniformGrid2D(
            output, xOffset, yOffset, xSize, ySize, frequency, seed
    );

(and then no problems next run, etc)

Yep, this latest set of stuff is with that set to true. I'll add an assert for the fnSimplex check

(Sorry in advance if this turns out to be some wonky FFI thing haha)

I've ran into the exact same problem. I was able to partially track it down, for some reason dynamic_cast<VoidPtrStorageType>( base ); returns null in SetSourceSIMDPtr in Generator.inl. That's the reason of the crash. Unfortunately in my project I cannot debug it further as the problem does not occur in debug builds (likely due to the fact that debug builds run a lot slower) and the variables I'd need for debugging it get optimized out somehow (or at least don't load on breakpoints).
Either way for now I'm simply re-creating the base generator and re-setting the source in derived generators when simdGeneratorPtr is null. Works, but obviously far from ideal.

That does sound weird. Are you sure the generator you are setting the source for and the source are both not null?
Can you show your workaround I'm not 100% sure what you mean

It seems like with the latest release this problem doesn't happen anymore, so it's probably fine to just close out this issue :u


cFS Bundle Integration Candidate: Caelum+dev3

Checklist (Please check before submitting)

[x] I reviewed the Contributing Guide.
[x] I signed and emailed the appropriate Contributor License agreement to<EMAIL_ADDRESS>and copied<EMAIL_ADDRESS>
Describe the contribution
PR #413

Fix #412, git error in CodeQL Analyze Action

Also includes:
cFE v7.0.0-rc4+dev70
nasa/cFE#2041, Improve CFE_SB_IsValidMsgId handler
nasa/cFE#2034, Update CodeQL workflow
nasa/cFE#2042, Replace CFE_SB_ValueToMsgId(0) with CFE_SB_INVALID_MSG_ID
osal v6.0.0-rc4+dev32
nasa/osal#1209, typesafe definition of osal_id_t
sample_app v1.3.0-rc4+dev9
nasa/sample_app#165, Use preferred UT patterns
Testing performed
cFS Bundle Checks https://github.com/nasa/cFE/pull/2043/checks
cFE Checks https://github.com/nasa/cFE/pull/2043/checks
Note that CodeQL workflow will fail until nasa/cFS#413 is merged into main branch. See passing test in that PR.
Expected behavior changes
See PRs
System(s) tested on
Ubuntu 18.04
RTEMS 5
RTEMS 4.11
Additional context
See also https://github.com/nasa/cFE/pull/2043
Third party code
None
Contributor Info - All information REQUIRED for consideration of pull request
@skliper
@paulober
@jphickey

Had to do a force push to main, correct hash is f787d2cd624cb7aa63d6aec8befe9eb8e46f305f


Remove ol/layer/MapboxVector to avoid a circular dependency

This pull request removes the circular ol <-> ol-mapbox-style dependency by removing ol/layer/MapboxVector. Since the creation of the MapboxVector layer, the ol-mapbox-style's API has advanced a lot, so now it is very easy to consume a Mapbox-hosted vector style directly with ol-mapbox-style's applyStyle() function. The mapbox-vector-layer.html example has been updated accordingly, and I added a minimal example for the required change in the upgrade notes.
This is a breaking change.

Would it make sense to have something like the MapboxVector available in ol-mapbox-style?

@tschau Oh yes! I'm going to do that.

@tschaub Updated the pull request to use the brand new MapboxVectorLayer from ol-mapbox-style@11.

@tschaub Is it ok for you if I merge this? ol-mapbox-style now has a MapboxVectorLayer named export, which is basically a copy of the removed ol/layer/MapboxVector.

Looks like a rendering test is failing: https://github.com/openlayers/openlayers/actions/runs/5916085353/job/16042971717#step:5:43
Not in a place where I can check the artifacts.  Maybe an unrelated/ephemeral failure, but I noticed the same failed for another PR.

@tschaub Looks unrelated, in both cases. I'm going to investigate.

@tschaub #15032 should fix that rendering test issue.


"New file relative to current view" command

It would be nice to have a "New file relative to current view" command or change the "New File" command to operate relative to the current view (if triggered from command palette). I usually want new files to be in the same directory as the file I am currently working on so I would like to have that option.

Seems do be a duplicate of #14


Issues 556,557

Coverage decreased (-0.4%) to 82.218% when pulling cb251de25ce7ccff74002deda9778715b07b288d on issues-556,557 into 70fa5f780abd81901444b1d1fc617646eb7d258e on master.

@homu r+

:pushpin: Commit cb251de has been approved by kbknapp

:hourglass: Testing commit cb251de with merge 453cff5...

:sunny: Test successful - status


Explosive Barrel

Description
Feature: #353
The purpose of this task ticket is to implement a placeable explosive barrel which will explode when another explosive is detonated near it. The explosive barrel will have the ability to set off surrounding explosives, such as other explosive barrels, to allow explosions to chain and add further depth to the feature (e.g. setting up booby traps for the enemies).
Dependencies

[x] ExplosiveComponent

Milestones
List of steps that need to be completed for this task.

[x] Create a new placeable structure for the explosive barrel.
[x] Find and implement explosive barrel assets.

[x] Explosion sound
[x] Explosion effect
[x] Explosive barrel image

[x] Make it so that the explosive barrel will detonate when surrounding explosives detonate.

Completion Deadline: Oct. 2
Documentation

TBC

Member

Rowan (@rowan-gray)
Yugansh (@Yugansh-Uq)

Completed


problem installing meta toolkit in windows 10(problem in ICU)

I have been trying to setup meta toolkit from 2 days and have went through all the forums but couldn’t get a possible solution.
I am working on windows 10 and have installed msys2 from msys2 website and has followed meta-toolkit setup-guide.html#windows-build-guide
I have also tried git clone --branch develop --single-branch https://github.com/meta-toolkit/meta.git
but this hasn’t worked. kindly help
The process stucks here
Unpacking C:/msys32/home/Dell/meta/build/deps/icu-63.1/src/ExternalICU/source/data/in/icudt63l.dat and generating out/tmp/icudata.lst (list of data files)
/bin/sh: -c: line 0: syntax error near unexpected token (' /bin/sh: -c: line 0:PATH=…/stubdata:…/tools/ctestfw:…/lib:$PATH …/bin/pkgdata -O …/data/icupkg.inc -q -c -s Microsoft Windows [Version 10.0.16299.125] © 2017 Microsoft Corporation. All rights reserved. C:/msys32/home/Dell/meta/build/deps/icu-63.1/src/ExternalICU-build/data>/out/build/icudt63l -d …/lib -e icudt63 -T ./out/tmp -p icudt63l -m static -r 63 -L icudt ./out/tmp/icudata.lst’
make[4]: *** [Makefile:193: packagedata] Error 1
make[3]: *** [Makefile:153: all-recursive] Error 2
make[2]: *** [CMakeFiles/ExternalICU.dir/build.make:137: deps/icu-63.1/src/ExternalICU-stamp/ExternalICU-build] Error 2
make[1]: *** [CMakeFiles/Makefile2:1374: CMakeFiles/ExternalICU.dir/all] Error 2
make: *** [Makefile:150: all] Error 2

Having the same issue in Ubuntu 18.04.4

i have exactly the same error you have . please tell me how to solve this problem,thanks!

This affects all systems, not just Windows 10.  The fix is easy, however, just edit CMakeLists.txt and change the line:
URL http://download.icu-project.org/files/icu4c/58.2/icu4c-58_2-src.tgz
to:
URL https://github.com/unicode-org/icu/releases/download/release-58-2/icu4c-58_2-src.tgz


Properly Forward Constants Through BlackBoxes

For example, currently it seems like a FixedPoint / constant somehow loses the info that the denom is constant and then drops in the expensive version of the blackbox

Seems ok now


Update Samples app to latest images

Steps to reproduce
NodeJS and OpenSSL must be updated to latest versions/packages.
Observed behavior
The NodeJS and OpenSSL version have known vulnerabilities and must be updated to latest.
NodeJs (Npm) Security Update for fast-xml-parser
NodeJs (Npm) Security Update for semver
Alpine Linux Security Update for Open Secure Sockets Layer (OpenSSL)
Desired behavior
All dependencies are at the latest released version.
Workaround
No response
rad Version
n/a
Operating system
No response
Additional context
No response
Would you like to support us?

[ ] Yes, I would like to support you

AB#11150

The image getting flagged as vulnerable was a very old version of our demo app stored in ACR (we have since renamed the app and moved our samples images to GHCR). The image was deleted and is no longer getting flagged as vulnerable. I redeployed our latest samples app image to a new cluster and that has not been flagged for about a week so I'm going to close this issue for now. We can reopen if the images start getting flagged again

Completed in Sprint 37


Remove License from module doc string

The license lines start with # and they are in the doc string. It should be either of those. Since the license may not be important in help(), we can make it a comment.

Thanks @MarkoMackic


PROPOSAL: make appending to current environment list the default

Problem
Although we don't have this implemented yet, once we have our uenv command, one might expect that one can mount multiple images by running the command multiple times, e.g.:
$ uenv mount imageA
$ uenv mount imageB /user-tools
$ uenv list
imageA /user-environment
imageB /user-tools

The current implementation of the --uenv option overrides any currently mounted images. If a user has a default environment mounted, it is unexpected to lose it if they subsequently mount a tools environment (for example) when running a slurm job.
$ uenv list
imageA /user-environment
$ srun --uenv=imageB:/user-tools /user-environment/bin/gcc
command not found: gcc

A similar problem occurs when using sbatch to set a uenv and then running srun with another uenv: the command executed by srun no longer has access to the uenv given to sbatch.
This may become especially problematic if we provide a default user environment that a user would expect to be always available.
One solution that works right now is to use the envvar that we have to keep track of mounted images:
srun --uenv=$UENV_MOUNT_LIST,tools.sqfs:/user-tools findmnt /user-tools
This has the disadvantages that

our use of $UENV_MOUNT_LIST is exposed to the user which could change or disappear in the future,
the format of $UENV_MOUNT_LIST has to be consistent with the syntax that --uenv accepts,
the behaviour is unexpected given how the uenv command may work,
there is extra noise every time a user wants to add to the default environment.

Proposal

Make the default action of --uenv be to extend the current list of images.
Add --uenv-clear which would effectively set $UENV_MOUNT_LIST to "" before adding any images (potentially) listed in --uenv.

Reasoning

The user is forced to explicitly state that they wish to clear the environment and load a completely new set.
--uenv behaves more list uenv
We are more flexible in deciding how to propagate/track our list of mounted images.

Potential Issues

User may attempt (inadvertently) to mount duplicate images to the same or different mount point
Do we complicate the case where a user wants to run commands from different user environments mounted on /user-environment. In this case the syntax would be:

srun --uenv-clear --uenv=... command
srun --uenv-clear --uenv=... command

I agree, that when multiple images can be mounted, the user could expect that uenv mount .. can be called repeatedly, each time appending to or overriding already mounted images.
In the current implementation (setuid squashfs-mount and slurm plugin), prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) is called in the end. This prevents child processes from gaining new privileges. It also prevents squashfs-mount to be called recursively. Commenting that line might be a potential security issue.
We first need to figure out if PR_SET_NO_NEW_PRIVS can be safely removed or not.

The limitation that we can make successive calls to uenv start is, as @simonpintarelli points out, a technical limitation of the current implementation.
However it also reflects a concious design decision: the user environments are designed so that one environment canbe started at a time.
That is, the running environment has to be stopped before a new environment can be started.
The original design was that all environments could be mounted at /user-environment, which was extended to support multiple (image,mount) pairs to support the specific workflow of side-loading tools.
The only workflow where mounting an additional image would make sense with two mount points like this, would be if a user wanted to load additional tools after starting an image.
For the uenv command line utility, I have been thinking about an interface like the following:
# start the gromacs 2019 environment
uenv start gromacs.2019
uenv run gromacs.2019 --view=default srun -n4 -N1 gmx <args>

# start the gromacs 2019 environment with a "profiler" tools
uenv start gromacs.2019 --tools=profilers
uenv run gromacs.2019 --tools=profilers --view=default srun -n4 -N1 profile gmx <args>

Where the user doesn't provide the mount point - the tool automatically mountes everything at /user-environment.
To load tools, instead of providing a /tools mount point, a CLI flag --tools would always mount tools at /tools.


Add stale while revalidate values

What is the purpose of the change

Updates our caching strategy to allow users to receive cached values while fresh values are fetched in the background during the ttl - staleWhileRevalidate time window.
ClickUp Task
ClickUp Task URL
Brief Changelog

Update ttl values and add staleWhileRevalidate to all uses of cachified
Use cachified for timeout height
Increase consistency of setting ttl and staleWhileRevalidate params

Testing and Verifying

Notice faster load times while data is loaded in the background

Seems good, maybe we should start writing a readme inside the server repo to explain why and how caching system works, what do you think?

Good idea, I'll improve and update the README


[RHOAIENG-3551] - fastapi - Regular Expression Denial of Service (ReDoS)

Fixes CVE-2024-24762 - Regular Expression Denial of Service (ReDoS) Remove the fastapi when this is addressed:  https://issues.redhat.com/browse/RHOAIENG-3894 or ray releses a new version that removes the fastapi version pinning and it gets updated on KServe

What this PR does / why we need it:
Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes #
Type of changes
Please delete options that are not relevant.

[ ] Bug fix (non-breaking change which fixes an issue)
[ ] New feature (non-breaking change which adds functionality)
[ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
[ ] This change requires a documentation update

Feature/Issue validation/testing:
Please describe the tests that you ran to verify your changes and relevant result summary. Provide instructions so it can be reproduced.
Please also list any relevant details for your test configuration.

[ ] Test A

[ ] Test B

Logs

Special notes for your reviewer:

Please confirm that if this PR changes any image versions, then that's the sole change this PR makes.

Checklist:

[ ] Have you added unit/e2e tests that prove your fix is effective or that this feature works?
[ ] Has code been commented, particularly in hard-to-understand areas?
[ ] Have you made corresponding changes to the documentation?

Release note:

the failure seems not be related with the changes.


In correct information in this article

The statement in purple above "Permission levels are defined by SharePoint Online administrators in the SharePoint Online Administration Center"  is incorrect.

Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

ID: 4992d050-ba30-54b6-7970-4e66ff3995c3
Version Independent ID: ddc48376-3cb1-5491-7685-9ccc44be9f60
Content: New-SPOSiteGroup (sharepoint-online)
Content Source: sharepoint/sharepoint-ps/sharepoint-online/New-SPOSiteGroup.md
Service: sharepoint-powershell
GitHub Login: @trent-green
Microsoft Alias: trgreen

@officedocsbot assign @yogkumgit

Hello @Cloudmaister thanks for your feedback.
I created a pull request to propose improving that sentence, if it gets approved, an updated version of the article will be published.
Thanks

@trent-green Please merge the PR #4395

@get-itips  Thank you very much for the contribution and updating the documentation with PR. @Cloudmaister Hope this update is helpful for you. Thanks for taking out some time to open the issue. Appreciate and encourage you to do the same in future also.


Allow custom importers.

Fixes #24.
If a user passes in a custom importer option, this PR now passes that option through to node-sass. It also modifies the sass-extract specific importer to preprocess the filepath through any custom importers first.
node-sass accepts both sync and async versions of importer fns, and also accepts an array of fns or a single fn. This PR supports (and tests) all of those cases.
If the user, however, has an importer fn which returns { contents: <...> } (instead of { file: <...> }), that is not supported. It will still pass through to node-sass (so the files can be compiled properly), but sass-extract won't be able to extract variables from those imports. I think those would be unusable by sass-extract in any case?

Updated the PR to support custom importers which may return absolute import paths.


Implement FeatureSet canCallMagicCall and callMagicCall methods

Recently, I was attempting to call the lastSequenceId method of the
SequenceFeature, after adding the SequenceFeature to a TableGateway
object. However, on doing so, I discovered that both methods effectively
weren't implemented, despite what the manual alluded to. Given that I'm
adding this commit, along with the covering tests to implement the
functionality.

ping @ralphschindler

Thanks @mwillbanks!


the greater good

making this an abstract baseclass, but left in the main model for the time being.
@mparent61 @MichaelButkovic

Coverage decreased (-0.2%) to 86.027% when pulling 8974d0ef1322a80365bf649c9216582aee829a36 on infographics into dda168a3de679bc0c8b4c0f0486d015548a18e62 on master.

one thing that I noticed will be painful about the json fields, is that changing a serializer name will require some manual data migrations

LGTM

Coverage decreased (-0.2%) to 86.027% when pulling 5cd2b5ebbd92effc64a934322cb4302973aef513 on infographics into dda168a3de679bc0c8b4c0f0486d015548a18e62 on master.

Coverage decreased (-0.2%) to 86.027% when pulling 5cd2b5ebbd92effc64a934322cb4302973aef513 on infographics into dda168a3de679bc0c8b4c0f0486d015548a18e62 on master.


Errno2: No such file or directory for Metadata

Traceback (most recent call last):
File "/nft-generator-py-main/index.py", line 225, in
"description": "Space Cowboys NFT Collection"
File "/nft-generator-py-main/index.py", line 57, in generate_unique_images
with open('./metadata/all-objects.json', 'w') as outfile:
FileNotFoundError: [Errno 2] No such file or directory: './metadata/all-objects.json'

Nvm, worked my way out.
I've just changed metadata folders absolute path.


Wrong link attribute

https://github.com/microsoft/BotFramework-WebChat/blob/31291d588e782bdef63d8f37ae01e81ea54cfd87/packages/bundle/src/renderMarkdown.js#L75
Should not be 'rel' here?

You are right.
Correct:
Wrong:


make sure path is the same on windows and unix

Not necessary anymore, because another PR fixed the issue


Documentation out of date

Describe the bug
Documentation "setup labeling interface is out of date"
Link
Link to "contribute to labeling Config" are broken.
To Reproduce
Steps to reproduce the behavior:
Go to docs
Expected behavior
Links should work
Screenshots
If applicable, add screenshots to help explain your problem.
Environment (please complete the following information):

OS: [e.g. iOS]
Label Studio Version [e.g. 0.8.0]

Additional context
Add any other context about the problem here.

@smoreface

Thanks for the report! I'll fix this soon :)


Need an organization invitation to manage the new theme I submitted.

Just over a week ago my theme for dmenu was brought into the org, but I couldn't accept my invitation before it ran out. Could I please be sent a new one?

I just sent you an invitation to join the organization 😅


ssh_connection retries seems not used

Which version of Ansible are you running?
ansible==2.9.1
mitogen==0.2.9

Is your version of Ansible patched in any way?
no

Are you running with any custom modules, or module_utils loaded?
no

Have you tried the latest master version from Git?
no

Do you have some idea of what the underlying problem may be?
https://mitogen.networkgenomics.com/ansible_detailed.html#common-problems has
instructions to help figure out the likely cause and how to gather relevant
logs.

Mention your host and target OS and versions
ubuntu 16.04

Mention your host and target Python versions
python 3.5

It seems mitogen does not retry ssh connection if a host is unreachable.
Trying to reproduce issue with an unreachable host and ssh retries setup to 5:
ansible.cfg
[ssh_connection]
retries = 5

Play
- name: test
   hosts: host_test
   # strategy: mitogen_linear
   strategy: linear
   gather_facts: False
   tasks:
     - file:
         path="/tmp/test"
         state=touch

Logs
with strategy: linear
PLAY [test] *******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
META: ran handlers

TASK [file] *******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /tmp/test.yml:40
Thursday 28 November 2019  18:20:31 +0100 (0:00:00.041)       0:00:00.041 *****
Using module file /usr/lib/python3.5/site-packages/ansible/modules/files/file.py
Pipelining is enabled.
<host_test> ESTABLISH SSH CONNECTION FOR USER: root
<host_test> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4b4c99a891 host_test '/bin/sh -c '"'"'/usr/bin/python3 && sleep 0'"'"''
<host_test> ssh_retry: attempt: 1, ssh return code is 255. cmd ([b'ssh', b'-C', b'-o', b'ControlMaster=auto', b'-o', b'ControlPersist=60s', b'-o', b'StrictHostKeyChecking=no', b'-o', b'KbdInteractiveAuthentication=no', b'-o', b'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', b'-o', b'PasswordAuthentication=no', b'-o', b'User="root"', b'-o', b'ConnectTimeout=10', b'-o', b'ControlPath=/root/.ansible/cp/4b4c99a891', b'host_test', b"/bin/sh -c '/usr/bin/python3 && sleep 0'"]...), pausing for 0 seconds
<host_test> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4b4c99a891 host_test '/bin/sh -c '"'"'/usr/bin/python3 && sleep 0'"'"''
<host_test> ssh_retry: attempt: 2, ssh return code is 255. cmd ([b'ssh', b'-C', b'-o', b'ControlMaster=auto', b'-o', b'ControlPersist=60s', b'-o', b'StrictHostKeyChecking=no', b'-o', b'KbdInteractiveAuthentication=no', b'-o', b'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', b'-o', b'PasswordAuthentication=no', b'-o', b'User="root"', b'-o', b'ConnectTimeout=10', b'-o', b'ControlPath=/root/.ansible/cp/4b4c99a891', b'host_test', b"/bin/sh -c '/usr/bin/python3 && sleep 0'"]...), pausing for 1 seconds
<host_test> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4b4c99a891 host_test '/bin/sh -c '"'"'/usr/bin/python3 && sleep 0'"'"''
<host_test> ssh_retry: attempt: 3, ssh return code is 255. cmd ([b'ssh', b'-C', b'-o', b'ControlMaster=auto', b'-o', b'ControlPersist=60s', b'-o', b'StrictHostKeyChecking=no', b'-o', b'KbdInteractiveAuthentication=no', b'-o', b'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', b'-o', b'PasswordAuthentication=no', b'-o', b'User="root"', b'-o', b'ConnectTimeout=10', b'-o', b'ControlPath=/root/.ansible/cp/4b4c99a891', b'host_test', b"/bin/sh -c '/usr/bin/python3 && sleep 0'"]...), pausing for 3 seconds
<host_test> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4b4c99a891 host_test '/bin/sh -c '"'"'/usr/bin/python3 && sleep 0'"'"''
<host_test> ssh_retry: attempt: 4, ssh return code is 255. cmd ([b'ssh', b'-C', b'-o', b'ControlMaster=auto', b'-o', b'ControlPersist=60s', b'-o', b'StrictHostKeyChecking=no', b'-o', b'KbdInteractiveAuthentication=no', b'-o', b'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', b'-o', b'PasswordAuthentication=no', b'-o', b'User="root"', b'-o', b'ConnectTimeout=10', b'-o', b'ControlPath=/root/.ansible/cp/4b4c99a891', b'host_test', b"/bin/sh -c '/usr/bin/python3 && sleep 0'"]...), pausing for 7 seconds
<host_test> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4b4c99a891 host_test '/bin/sh -c '"'"'/usr/bin/python3 && sleep 0'"'"''
<host_test> ssh_retry: attempt: 5, ssh return code is 255. cmd ([b'ssh', b'-C', b'-o', b'ControlMaster=auto', b'-o', b'ControlPersist=60s', b'-o', b'StrictHostKeyChecking=no', b'-o', b'KbdInteractiveAuthentication=no', b'-o', b'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', b'-o', b'PasswordAuthentication=no', b'-o', b'User="root"', b'-o', b'ConnectTimeout=10', b'-o', b'ControlPath=/root/.ansible/cp/4b4c99a891', b'host_test', b"/bin/sh -c '/usr/bin/python3 && sleep 0'"]...), pausing for 15 seconds
<host_test> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/4b4c99a891 host_test '/bin/sh -c '"'"'/usr/bin/python3 && sleep 0'"'"''
fatal: [host_test]: UNREACHABLE! => changed=false
  msg: |-
    Data could not be sent to remote host "host_test". Make sure this host can be reached over ssh: ssh: connect to host host_test port 22: Connection refused
  unreachable: true

with  strategy: mitogen_linear
PLAYBOOK: test.yml **************************************************************************************************************************************************************************************************************************
1 plays in /tmp/test.yml

PLAY [test] *********************************************************************************************************************************************************************************************************************************
[top  4658] 18:18:40.276317 D ansible_mitogen.affinity: CPU mask for Ansible top-level process: 0x000002
[top  4658] 18:18:40.277332 D ansible_mitogen.process: inherited open file limits: soft=1024 hard=1048576
[top  4658] 18:18:40.277877 D ansible_mitogen.process: raised soft open file limit from 1024 to 1048576
[mux  4666] 18:18:40.284712 D ansible_mitogen.affinity: CPU mask for MuxProcess 0: 0x000001
[mux  4666] 18:18:40.301380 D mitogen.service: Pool(62b0, size=32, th='MainThread'): initialized
[mux  4666] 18:18:40.303930 D ansible_mitogen.process: Service pool configured: size=32
META: ran handlers

TASK [file] *********************************************************************************************************************************************************************************************************************************
task path: /tmp/test.yml:40
Thursday 28 November 2019  18:18:40 +0100 (0:00:00.098)       0:00:00.098 *****
[task 4700] 18:18:40.332803 D ansible_mitogen.affinity: CPU mask for WorkerProcess: 0x000004
[task 4700] 18:18:40.359046 D ansible_mitogen.process: will use multiplexer 0 (/tmp/mitogen_unix_peubdg0l.sock) to connect to "host_test"
[task 4700] 18:18:40.359485 D mitogen.unix: client: connecting to /tmp/mitogen_unix_peubdg0l.sock
[task 4700] 18:18:40.360498 D mitogen.unix: client: local ID is 1, remote is 0
[mux  4666] 18:18:40.360818 D mitogen.unix: listener: accepted connection from PID 4700: unix_client.4700
[mux  4666] 18:18:40.366643 D mitogen.parent: creating connection to context 2 using mitogen.ssh
[mux  4666] 18:18:40.519155 D mitogen.parent: command line for Connection(None): ssh -o "LogLevel ERROR" -l root -o "Compression yes" -o "ServerAliveInterval 30" -o "ServerAliveCountMax 10" -o "BatchMode yes" -o "StrictHostKeyChecking no" -o "UserKnownHostsFile /dev/null" -o "GlobalKnownHostsFile /dev/null" -C -o ControlMaster=auto -o ControlPersist=60s host_test /usr/bin/python3 -c "'import codecs,os,sys;_=codecs.decode;exec(_(_(\"eNqFkcFLwzAUxs/rX9FbEha6dJMOCgFlB/EgQhF30CHtkm7BLglp2jr/et86ce08eHs/3vfe9+Ulo2tu6sgqKzEJHO0GpMoQoDTuA5M0mEAtGjvHjMaMkQtndEgOuvGZt5WpJc6G4IawHkIHAIb1Eeyr3IPrIeQ8RCJ3ndIozLXom/JTbhufF5Xs27OmdrNC6Zk9+r3RCHJOrmRT3g+20tXK6Nd0seltpW6VA0Z32f0LQxs+HjtrACs8btAxThE+KG92UqfOGH+bi4PSi2hXmSKvIiHb0/saEZl2H2np05skSQgiAWzvnPISxxQ9Pjw/McbeNIJUWyPg+CRY8Xd8Or8wVmo4OnIFIpGTucDxks2XhKIvZWFTaflFt6aoK9DpR0r7Y7Dq6/OVr9Tdf+q/KeNxyt//m5Nvc4q5XA==\".encode(),\"base64\"),\"zip\"))'"
[mux  4666] 18:18:40.531862 D mitogen.parent: child for Connection(None) started: pid:4703 stdin:77 stdout:77 stderr:79
[mux  4666] 18:18:40.618116 D mitogen.parent: ssh.host_test: (unrecognized): ssh: connect to host host_test port 22: Connection refused
[mux  4666] 18:18:40.619316 D mitogen: <Side of ssh.host_test fd 79>: empty read, disconnecting
[mux  4666] 18:18:40.621030 D mitogen: SetupProtocol(ssh.host_test): disconnecting
[mux  4666] 18:18:40.622383 D mitogen: <Side of ssh.host_test fd 77>: empty read, disconnecting
[mux  4666] 18:18:40.623188 D mitogen.parent: failing connection ssh.host_test due to EofError('EOF on stream; last 100 lines received:\nssh: connect to host host_test port 22: Connection refused\r',)
[mux  4666] 18:18:40.623931 D mitogen.parent: PopenProcess ssh.host_test pid 4703: exited with return code 255
[mux  4666] 18:18:40.624371 D mitogen: BootstrapProtocol(ssh.host_test): disconnecting
[mux  4666] 18:18:40.625550 D mitogen: BootstrapProtocol(ssh.host_test): disconnecting
[task 4700] 18:18:40.627460 D mitogen: MitogenProtocol(unix_listener.4666): disconnecting
[mux  4666] 18:18:40.628798 D mitogen: <Side of unix_client.4700 fd 76>: empty read, disconnecting
[task 4700] 18:18:40.628844 D mitogen: Waker(fd=11/12): disconnecting
[mux  4666] 18:18:40.629390 D mitogen: MitogenProtocol(unix_client.4700): disconnecting
[task 4700] 18:18:40.630188 D mitogen: Router(Broker(9898)): stats: 0 module requests in 0 ms, 0 sent (0 ms minify time), 0 negative responses. Sent 0.0 kb total, 0.0 kb avg.
fatal: [host_test]: UNREACHABLE! => changed=false
  msg: |-
    EOF on stream; last 100 lines received:
    ssh: connect to host host_test port 22: Connection refused
  unreachable: true

I just ran into this, too. I'd really like to see support for SSH retries. I often run playbooks with tons of hosts, and often enough the first SSH connection to some of them fails (for whatever reason). Using Ansible's default SSH connection plugin with retries solves this as the second connection attempt works for those few hosts, but with the mitogen plugin no retries are made.
I'd be very grateful if support for ANSIBLE_SSH_RETRIES / [ssh_connection] retries=… was implemented.

Have there been any work arounds or updates on this issue?  In our use case we have connection issues based on ping and would like to retry some of those hosts as well.  Prior to using mitogen, we weren't experiencing this issue.

I'm seeing the same thing with none of this configuration not being used:
[ssh_connection]
ansible_ssh_timeout = 60s
ssh_args=-o PasswordAuthentication=no -o ConnectTimeout=60s -o ControlMaster=auto -o ControlPersist=60s -o ControlPath=/tmp/ansible-ssh-%h-%p-%r


Finding BluetoothState.unknown on iOS

Hello.
I have an app that shows the BluetoothState in the first screen.
It's weird, but most of the times (60%) when the app comes from TestFlight (and a few times with a normal build, I would say 2%) when I start the app, I receive the BluetoothState.unknown on iOS.
I have the last version, but it's quite curious. I've tried to find this issue, if anyone had it, but I can't find it.
It's quite difficult to recreate because I have to constantly kill the app and open it again to be lucky and recreate it, and the only good scenario to recreate it is on TestFlight.
What could be causing it?
I've checked and the permissions are ok (when they're not, the state is BluetoothState.unauthorized).

A nice update.
I've found out that this issue happens only when you tap the app from TestFlight directly from your gallery of apps.
If you tap TestFlight > [App] > "OPEN", it doesn't happen!
Not sure if now this is a TestFlight error or an issue with the library itself being in a nutshell.

Was due to leaving a static reference of its state.
Bad boy @RafaRuiz .

I encounter the same issue when  normal boot the example app without TestFlight.

@debugerer I don't know how to help without any more details. My case wasn't the example app, it was more overengineered and I left static Streams with the BluetoothState

Just run the example app,  you will reproduce the bug more than 50% .