RFC: new rand_core crate, rand adaptations

This RFC seeks to introduce a rand_core trait, and make a few changes to rand for compatibility.
Rendered link
Parent RFC — for reference on the development of this RFC
Still undecided in this RFC:

[ ] Semantic meaning of CryptoRng
[ ] Error type
[ ] SeedableRng stream support
[x] Trait for seek support [can wait until later]
[x] Add next_u128?

I want to suggest to rename the Rng trait to NonCryptoRng, so you'd have CryptoRng and NonCryptoRng.
I have seen to too many people out there using int rand(void) for cryptographic purposes and making it right in Rust really comes low cost.

I know that some Rngs can seek, but how many of them? The seeking trait seems like an easy thing to add later if we can't come to a quick conclusion. Individual rngs are also allowed to provide methods beyond just the traits as well, until then.
Can the Error type be an associated type? That way each rng can pick their own enum of how they wish to fail. That would only work with design 2 or design 3, but it seems good if either of those are picked.
And for default methods, if we use options 2 or 3, then next_u64 can default to two next_u32 calls. We would not need a default for try_fill, but we could also have that default to filling the bytes with next_u64 calls I suppose.

@manuels I know it sounds cavalier, but I'm not so concerned, since (a) the documentation should recommend use of OsRng which is the best option, (b) the "convenient" generator, thread_rng, may not be a recommended crypto RNG but it will still be something for which there is no known practical attack, and (c) in the worst-case when a very insecure generator is used against all recommendations, it should still be seeded from OsRng, so there will still be as much entropy as the internal state can hold. That said, CryptoRng will be right next to Rng, so should be plenty visible enough? It's not like C where you're supposed to use a completely different part of the library.
@Lokathor "Can the Error type be an associated type?" Technically I guess yes, except for uses not on Rngs. But practically, it would be a huge pain to work with (multiple error types, much more explicit speification needed).

I think the comment by @manuels is in line with Rust's tendency to make unsafe names longer, and dangerous-sounding. It's hard to miss that you've done something less safe.

We figured out that Rngs never have many errors @Lokathor except perhaps for OsRng but even there they denote system miss-configuration and a &'static str suffices.  Imagine if say JoeBSD handles the system PRNG poorly by providing only an entropy pool that quickly gets exhausted then that's a bug in JoeBSD but if they won't fix it then OsRng should wrap the system PRNG on JoeBSD inside a CSPRNG that periodically reseeds to prevent exhaustion.  It's similar if you've some fancy collaborative randomness daemon running.
I noticed the existing inherent method for seek on ChaChaRng also sets the nonce.  How should one set the nonce on ChaChaRng if we use SeekableRng?  Just another inherent method?  Also, is another SeekableRng planned?  If not, then maybe it's more important to expose inherent methods that do ChaChaRng well.

I feel the best design would be something like this. The main advantage that we naturally solve CryptoRng error problem with zero friction for no_std crates. (also OsRng will be able to pass io::Error) Additionally type system will know if RNG is indeed infallible, so users will be able to write R: CryptoRng<Error=!> if deemed necessary.
But the big disadvantage is that it relies on two currently unstable features. As written in the RFC we can replace never type with blank enum, but I don't think we should stabilize rand with this design without stabilization of those both features. Other small issue is that implementing fallible RNG will be a bit inconvenient and the best approach would probably to use private RNG method for filing bytes which will be used for fill and try_fill implementations. But I think this issue is quite insignificant. Also if I recall correctly there were concerns that associated type will make it harder to use CryptoRng, but I couldn't come up with examples which will support this opinion.
Regarding default implementations, I started to think that it will be better to include default implementation for fill in terms of next_u64 and leave both next_u32 and next_u64 as required methods, but I guess it's a matter of preference.
About next_u128: if I am not mistaken we'll have to keep the respective feature flag even after u128 stabilization or somehow convey that this feature flag is unstable. Is it worth the trouble? Shouldn't we simply wait u128 stabilization? Hopefully we'll get it relatively soon. (AFAIK only this issue is blocking it)
Question about SeedFromRng, it's not quite clear from the RFC what kind of Result are you using there, probably worth to clarify it.
Also please clarify naming: do you suggest to use rand-core, rand-os, etc. or rand_core, rand_os, etc.? I think for crate names we should use hyphen, not underscore.

I noticed that the i128-support feature flag is not very ergonomic for other crates that implement an RNG. Every one of them now has to add a similar feature flag in cargo.toml, at the top level file, and in the implementations. next_u128 should at least provide a default implementation. This seems sensible to me anyway, as an implementation that is more optimal than combining two u64's (e.g. one that operates natively on u128's) should be rare.

My thoughts about the SeedableRng trait:
What use cases are we serving with reseed? Simple deterministic RNGs used in games etc. that should produce a specific sequence? Then it seem not very useful to mel, as than it should be just as fast and ergonomic to use from_seed.
If we are talking about stronger RNGs, or even cryptographic ones, there is sometimes the suggestion to reseed the RNG. That may just be overly cautious, but that is not for me to decide. In that case it would be best if this function was more similar to from_rng, taking an other RNG (OsRng) as a source.
I think there is nothing lost if reseed is just removed.

next_u128: agree, lets remove and (possibly) add after stabilisation with default impl
Removing reseed: good argument
- vs _ in crate names: no idea. I was trying to follow this change. They should have just banned - from the beginning IMO (to line up with in-lang identifiers).
Associated error type (@newpavlov): seems excessively complicated to me. Also "whether an RNG is fallible" seems pretty unimportant, given that error rates will be extremely low. Finally, you wrote a generic function, get_key, to solve a simple problem... what happens when you have multiple sources of error to handle (e.g. creating and using a PRNG seeded from OsRng)? Having a uniform error type makes this much simpler.

@dhardy
OsRng and external RNGs will simply use io::Error (so e.g. in NewSeeded you will just use io::Result for new method), if you fix RNG types you fix error types as well, so working with them will be no different from the usual Rust code. It could make generic code a bit more verbose, but I think it's better encode information into type system if we can and allow crate authors to choose, than use some opaque type. Also I very much doubt application which use two fallible RNGs will be common enough to even consider such use cases. Could you please provide examples in which associated error type will be introduce unwanted complications?

Initially I'd imagined SeedableRng::reseed produced a new internal state by combining the current internal state with external state, but that's often false and thus confusing.
I kinda wondered if SeedableRng::reseed is required because (a) if R : Rng then &mut R : Rng so (b) ReseedingRng must operate on &mut R, but no this strange Reseeder<R> trait avoids that and just does *rng =  assignments anyways.
I suppose SeedableRng::reseed might improve constructs similar to ThreadRng but currently I do not see how.

Support for seeding from an u64 (SeedableRng<64>) seems like a good idea to me.
Seeding with an u64 should result in a RNG with a chance of 2^64 of being different from one other generator. If we look at the birthday problem, there is a 50% chance of getting the same generator a second time after 2^32 random initialisations. This drops quickly to only a couple of percents for 2^30. These numbers are very large, you would need about 8gb to just store the state of all the generators!. So initialising with an u64 seems good enough for almost any purpose to me.
Initialising from an u32 would give a change of ~1% to get the same generator after ~2^14 (not checked the numbers here). So after about 15.000 initialisations. If we want to support SeedableRng as a generally useful way to create a new RNG, and not only as a way to get a reproducable RNG for games and simulators etc., u32 would be to small.
Initialising with an u64 insteat of as many bits as a RNGs state would also allow one to spare the OsRng a bit, or some other generator used for initialisation. If the source generator returns really random numbers, I have seen the suggestion to treat the numbers returned by it as precious. But current OS generators don't fall in this category (unlike something like [www.random.org]), so this is not a strong point.
A disadvantage is that it makes it more difficult to write a correct initialization routine, but I think this is for most generators a solved problem.
This are all not very important arguments. The arguments in the RFC to include it for reproducability are best.
Seeding by slices:
I don't agree that seeding a part of the state with 0's is perfectly valid. Xorshift for example would be significantly weakened by it. And while ISAAC has a complex initialisation routine, I would not trust one initialised with a (large) number of zeros. I would suggest a panic if the slice is smaller than the required amount.
I do like the proposals for an associated type or fn seed_len() -> u32. Of byte-slices I am not really a fan. They are a bit slower to generate, and need to be transmuted / casted to be consumed. I think all generators store their state using 32 or 64-bit integers.
I don't really see a use case for implementing SeedableRng for multiple types, that is not served by seeding from an u64 and supplying a slice of the full seed size.
So my preferred treat would look like:
pub trait SeedableRng<Seed>: Rng {
    fn reseed_from_u64(&mut self, seed: u64);
    fn reseed(&mut self, Seed);
    fn seed_len() -> u32;
}

@burdges I don't fully understand what you are saying about reseeding, can you explain it some more?
And do you happen no know an RNG algorithm that can add entropy to its state?
On the other hand, if there is such an RNG, it can just as well expose such a function without it being part of the SeedableRng treat. Because I don't think it is all that common. But I have not looked all that hard at the different CSPRNG's yet.

@pitdicker "adding entropy" is pretty easy: just XOR the current state with new bits. Obviously there is a maximum amount of entropy the state can hold, so any definition of "add entropy" for a fixed size type must allow wastage. The point is simply that if somehow the "new entropy" is not fully trusted but the state was previously unknown, the new state is still unknown.
About your SeedableRng trait, in that case why not use an associated type? I don't see any advantage to your version if allowing only a single seed type, nor do I see a use for seed_len if the type is known:
pub trait SeedableRng: Rng {
    type Seed;
    fn reseed_from_u64(&mut self, seed: u64);
    fn reseed(&mut self, Self::Seed);
}

@newpavlov take a look at this. It already has to deal with two different sources of errors (OsRng and Self: SeedFromRng). How's that work with your associated error types?

@dhardy you are completely right :-)

Let me say first: It is great to see some treats proposed for new functionality like seeking and streams!
The biggest advantage they offer is the ability to create new RNGs of the same type, with no overlap, and without the need to get a new seed (from something like the OS). I think this is something very useful.
The link in the RFC to the PCG blog gives some great background info. Creating a new RNG from an existing one of the same type is something that I think is always possible.
For Xorshift, PCG and ChaCha it can be done by seeking to a point far enough away in the stream.
For ISAAC running a hash over its state should scramble it so much that it is basically guaranteed to be at a whole different point in its stream. Given that its period is huge, this should be fine.
PCG offers special support for multiple generators with the same seed, by changing the constants used internally.
I would not change the traits to much to accomodate for the design of PCG.
I don't know if this is possible, but I would implement it as part of the NewSeeded trait:
impl<XorshiftRng> NewSeeded for XorshiftRng {
    fn new() -> Result<Self> {
        // some jump function, next stream counter, hash etc.
    }
}

I was reasonably enthousiastic about seeking, until looking into it some more.
Seeking by a variable amount is super difficult for simple generators like Xorshift, Mersenne Twister etc. This paper describes the best method. A fixed amount is easier, because the jump constant can be generated by some computer algebra package.
I have not looked into it to deeply, but ChaCha seems to support jumping from an absolute position, and PCG only from the current position (unless you store the initial state somewhere).
One other thing that could be a problem: the amount it is possible to seek, is the same as the size of the period of the RNG, and maybe even larger (wrapping around). What to do with RNGs with periods like 128-bits, 256, 1024 or even larger? On the other hand, jumps that large seem only useful for the PCG party tricks... For any normal use jumping by an u64 seems sufficient (just like a period of 2^64 seems sufficient for a single stream of an RNG).
Next I tried to come up with some use cases. I don't have any real ones yet. It is something I have not seen other random libraries in other programming languages expose.
You already queestion if a trait for seek support should be included. I would say, lets wait until we have a few implementations to see what the possibilities of different RNGs are.

@pitdicker the only use-case I can personally see for seeking is to get a different stream (I think this is basically what set_counter is there for). And party tricks...
 I came up with a use-case for multiple streams a long time back: threading in agent-based sims where reproducibility is important. Given hundreds to millions of agents each undergoing stochastic processes and each needing a CPU-intensive update each step of the simulation, it is desirable to distribute the updates between CPU cores by giving each agent (or group of agents) its own PRNG; this could work several different ways (new agents deriving from a parent agent or new agents generated in-order by a master generator) and still be reproducible.

I agree, a big plus for multiple streams. Seeking by arbitrary amounts not so much yet. What do you think about using NewSeeded for streams?

Then a seperate trait would be better, something like this?
pub trait MultipleStreamsRng: Rng {
    fn new_stream(rng: &mut R) -> Self;
}

We should probably work out how ThreadRng works under the constraints that (a) the machinery used should be generic enough to exposed, and (b) it should run reasonably quickly, like chcha speed.
At first blush, we seemingly need this Reseeder mess in https://doc.rust-lang.org/rand/src/rand/lib.rs.html#904 because you cannot just pass OsRng as a type parameter.  You need some marker type instead because you want the ReseedingRng machinery to work off another user space PRNG as well.  If we cannot ditch Reseeder then the SeedableRng::reseed function sounds less valuable.
We could perhaps make this all resemble hashers somewhat more closely though :
pub trait BuildRng { // Renamed Reseeder
    type Rng: Rng;
    fn buld_rng(&mut self) -> Self::Rng;
}

pub struct OsRngBuilder;  // Renamed and exposed ThreadRngReseeder
impl BuildRng for OsRngBuilder {
    type Rng = OsRng;
    fn buld_rng() { OsRng:;new(); }
}
impl<'a,R: Rng> BuildRng for &'a mut R {  // Permit Rngs to be used to build directly
    type Rng = &'a mut R;
    fn buld_rng(&mut self) { *self }
}

We could maybe give SeedableRng control over when reseeding happened using a closure :
pub trait SeedableRng: Rng {
    type Seed: Rand;
    fn from_seed(Self::Seed) -> Self;
    type Boost: Rand = u64;
    fn boost_entropy<F: FnOnce() -> Boost>(&mut self, entropy_booster: F) -> bool {
        panic!("boost entropy unimplemented")
        // ChaChaRng boosts if its counter exceeds some constant.
        // Rngs that do not use a counter cannot know when to boost, but
        // some wrapper could give them a counter.
        // We could split this and boost_entropy into a separate trait to give
        // compile time errors instead of this panic.
    }
}
pub struct ReseedingRng<R, S> where
    R: SeedableRng,
    S: OsRngBuilder,
    <R as SeedableRng>::Seed: Rand,
{
    rng: R,
    src: S,
}
impl<R, S> ReseedingRng<R,S> {
    pub fn new(src) -> ReseedingRng<R,S> {
        let rng = R::from_seed( src.buld_rng().gen() ) );
        ReseedingRng { rng, src }
    }
    pub fn boost_entropy(&mut self) {
        self.rng.boost_entropy(|| { self.src.build_rng().gen() })
    }
}
impl<R, S> Rng for ReseedingRng<R, S> where ... { ... }

type ThreadRngInner = ReseedingRng<ChaChaRng, OsRngBuilder>;
pub struct ThreadRng {
    rng: Rc<RefCell<ThreadRngInner>>,
}

I donno if using a closure for flow control like that will always be as efficient as folks want, but presumably yes once it's wrapped and monomorphized inside ReseedingRng.

@pitdicker wrote:

The link in the RFC to the PCG blog gives some great background info. Creating a new RNG from an existing one of the same type is something that I think is always possible.
For Xorshift, PCG and ChaCha it can be done by seeking to a point far enough away in the stream.

I disagree! When dealing with a CSPRNG you should reseed the new RNG! Otherwise, the two RNG are correlated and somebody might be able (maybe by just reading enough information from the first RNG) to get information about the state of the other RNG.
Additionally, I have just heard arguments against renaming Rng to  Insecure/Simple/NonCryptoRng but not a single argument why you should keep the name Rng. Sorry, but saying we will put the distinction between Rng and CryptoRng in the docs is not enough from my point of view.
What should be the benefit of calling the insecure RNG just Rng? It is just sparing you to type NonCrypto.
Just put
import rng::NonCryptoRng as Rng;

in your rust file and everybody knows with what kind of RNG we are dealing with.
I simply do not see any benefit from calling the non-crypto RNG Rng. It is just a potential for security flaws.

@dhardy

take a look at this. It already has to deal with two different sources of errors (OsRng and Self: SeedFromRng). How's that work with your associated error types?

First, I don't quite get a motivation behind Result in the SeedFromRng, is there other possible errors except io::Error from OsRng? Second, CryptoRng does not have anything to deal with SeedFromRng in my proposal, they are orthogonal traits.
if you do not want to panic on seeding from another RNG (although I thought you've considered panicking an alright solution for non-crypto uses), then we need to add associated Error and try_* method(s) to Rng trait.
So first solution can be a small modification of your first design in the RFC:

Click to expand
pub trait Rng {
    type Error = !;

    fn next_u32(&mut self) -> u32;
    fn next_u64(&mut self) -> u64;

    fn fill(&mut self, dest: &mut [u8]);
    fn try_fill(&mut self, dest: &mut [u8]) -> Result<(), Self::Error>;

    // Maybe `try_next_*` methods as well, so `SeedFromRng` could seed from
    // u32 and u64 without panics
}

pub trait CryptoRng: Rng {}

pub trait SeedFromRng: Rng + Sized {
    // I think we do not need &mut R here because we implement Rng for &mut R
    fn from_rng<R: Rng>(rng: R) -> Result<Self, Self::Error>;
}

This way OsRng will naturally use io::Error which will bubble into NewSeededRng, plus we can drop std feature as it will not be used anymore.
Second solution would be to drop error management from NewSeededRng and SeedFromRng altogether, not a fan of it, but it's possible.
Regarding - vs _ I think we should ask opinion from Rust team. cc @alexcrichton
@manuels
You are missing the important point: CryptoRng is extension of Rng trait, so with your proposal we will have trait CryptoRng: NonCryptoRng which looks quite illogical to me. CSRNG is a subset of RNG, so current approach makes perfect sense.

As an aside, you should probably set the nonce for streams in ChaChaRng, so it sounds tricky to be polymorphic this.  I wonder if the right approach for nonce, seeking, etc. might be a wrapper type that turns a cipher from a cryptography crate into an Rng.

ISAAC has no big internal counter, so my ReseedingRng suggestion does not work with vanilla ISAAC unless you add a wrapper type. You could however modify ISAACs small internal counter to work.

I think a better name for CryptoRng might just be TryRng to parallel the Try trait and avoid the cryptographic semantics issues.

@newpavlov on the other hand NonCryptoRng (aka Rng currently) and CryptoRng are disjoint sets.
Maybe trait NonCryptoRng: Rng {} and trait CryptoRng: Rng {...} makes sense?

I think that only makes sense if there's some sort of jiggery we can pull so that you can't possibly implement both traits on the same RNG.

@burdges you talk about the ReseedingRng mess and then create a whole other mess around trying to re-use ChaChaRng's internal counter. It's not worth it, better to keep that mess packaged in the reseeding module.
@manuels streams are only useful when you want multiple reproducible streams of numbers. Reseeding (from external entropy) is therefore not an option.
Also @manuels read this bit I added to the RFC. I simply don't see the benefit of the mass breakage this would cause existing users.

@dhardy ok, apparently I misread the context. I agree.
@Lokathor I'm not sure if this is possible with the current trait/type system. However, I do not see the necessity for that: The implementor of an RNG usually knows much better what he is doing than the user. I really just want to prevent the users of an RNG to be able to shoot them-selfs unknowingly in the head.

Total bikeshedding, but (if we rearrange things into a new Sampleable trait) can the name for the generic method that makes an arbitrary value be called next instead of sample or gen? That way it lines up with the next_u32 and next_u64 and similar methods.

@newpavlov "First, I don't quite get a motivation behind Result in the SeedFromRng, is there other possible errors except errors produced by source RNG?" I guess you're correct, except that OsRng::new and OsRng::try_fill aren't required to have the same error type. I'm still not sold on using an associated type but maybe I'll have another look (when I have the time and energy). I really think you're over-complicating with stuff like TryRng and even the associated error type.
@manuels @Lokathor it's not just about preventing implementation of both, it's about semantics: some RNGs are "in between". Also, every PRNG is usable as a non-crypto RNG (if I want to use ChaCha in a simple game, I certainly can).

@Lokathor only argument I have on renaming gen → next is that it's less straightforward for existing rand users to upgrade.

It's true the closure trick splits the ReseedingRng logic between the Rng and the reseeding module, but the exposed counter actually splits it three ways.  Is there some benefit to exposing the counter because say people frequently reseed more than needed?  An associated constant in SeedableRng could hide the counter too.

I guess you're correct, except that OsRng::new and OsRng::try_fill aren't required to have the same error type.

On most of the platforms OsRng is defined simply as struct OsRng;, due to the fact that methods use syscalls. Exceptions are Redox and older Linux, which keep open rand file; and "nacl" which I personally think should be excluded from OsRng "platforms". So I io::Error is the perfect fit for OsRng::new().

I really think you're over-complicating with stuff like TryRng and even the associated error type.

Ehm, I haven't spoken about TryRng at all.

Is there some benefit to exposing the counter because say people frequently reseed more than needed?

@burdges don't forget that the primary reason to reseed is to regain entropy in case the algorithm lost it (poor initial seed or side-channel attack, or even weakness in the algorithm). Of course all these flaws are theoretical and normally not actual problems, but sometimes good security means dealing with unlikely cases too. Preventing looping is probably more of a happy side-effect of the reseeding code.

Does feeding the new entropy in just discard the old entropy and set you to a known point? Because if I used reseed i would expect to arrive at a known point in the number stream, in a deterministic/ re-producible way.

You can always write *rng = SomeRng::from_seed(seed); if you want that.  I think the main value of reseed, Reseeder, etc. is consuming less input from some more expensive Rng.  There is no appreciable difference between consuming one or four u64s, but frequently SeedableRng::Seed will be the Rngs entire internal state, which could be somewhat larger.

Okay, well that's different then. Currently reseed is a method of SeedableRng and it accepts a full seed value and sets the rng's seed to that value and none of that partial seed or entropy improvement stuff goes on (at least not as part of reseed itself)
I'm not an expert, but "frequently bigger than four u64 values" seems a little off. That's probably pretty rare, especially for non-crypto rngs.

Yeah, I think only Reseeder actually does this partial entropy augmentation stuff and reseed is not clearly defined.

@burdges Good point about including ThreadRng in the discussion about reseeding. It seems to be the big user of this functionality.
Some background for TreadRng:

comment by Alex Crichton its reason for existing
bug report about reseeding tread_rng
reseeding implementation

TreadRng uses ISAAC and reseeds it after generating 32kb. The goal is to have a reasonably fast semi-cryptographic RNG, hopefully of similar quality as OsRng.
As you say, what we want here (which is different from how it is currently implemented) is to boost the entropy of an Rng with the OsRng. For Crypto RNGs this is something more people may want. It does not seem to be strictly necessary, as the RNG itself should be secure enough. But I can't imagine better security for an RNG than one where its state is occasionally scrambled by some other random bytes. So, potentially useful.
Currently, this works with a ReseedingRng wrapper RNG. It needs the original RNG, the seeding RNG, a counter and a threshold after which to reseed. The original RNG needs some boost_entropy function (currently reseed).
I would propose to only include the basics necessary to support this functionality. And to only implement it for RNGs for which boosting entropy makes sense: cryptographic RNGs and strong RNGs like ISAAC. As we are serving here a use case that is completely different from that of SeedableRng (initialization of the RNG, simulations and games), I would propose a separate trait:
pub trait ReseedableRng: Sized {
    fn boost_entropy<R: Rng+?Sized>(rng: &mut R) -> Result<Self>;
    pub fn bytes_generated() -> u64;
}

bytes_generated is not strictly necessary. But if an RNG has an internal counter like ChaCha and ISAAC (yes, it has one ;-) ) it seems useful to me to expose it in the context of reseeding. Note that other cryptographic RNGs from the eSTREAM contest (HC-128, Rabbit, SOSEMANUK) don't have one. They could just return 0, or include a counter in their state. I don't think including a counter would be unreasonable for a security-oriented RNG.
I don't think Rand should expose a generic reseeding wrapper. That is because the moment you want to reseed very much depends on the user of the library. You can for example reseed after a certain number of bytes is generated. What would be a good threshold depends on the algorithm, and the paranoia(?) of the consumer. Another option is to reseed at some checkpoint, like when a new connection is set up (or something, I don't know anything about networking code). Or reseed when it is quiet (suggested back when Rust still had a runtime).
Not I'm getting on dangerous ground (crypto) but it seems to me the boost_entropy could work just as well if it only takes an u64. As long as it is used well (probably by modifying the state in a way similar to seed_from_u64), the RNG should now be in a completely different, unpredictable state. If you want stronger guarantees, just call boost_entropy multiple times. This has the advantage that it allows the caller to determine how much to boost the entropy with. And it makes the function infallible. It does not seem to make the implementation much more difficult, as you already have to same problem solved for seed_from_u64.
pub trait ReseedableRng: Sized {
    fn boost_entropy(&mut self, seed: u64);
    pub fn bytes_generated(&self) -> u64;
}

TreadRng would with this proposal become its own wrapper around IsaacWordRng (or maybe ChaChaRng), implementing most of the current ReseedingRng. This removes one abstraction, and with it a little complexity.
Is this a reasonable middle-ground?

@manuels

When dealing with a CSPRNG you should reseed the new RNG! If you just seek, the two RNG are correlated and somebody might be able (maybe by just reading enough information from the first RNG) to get information about the state of the other RNG.

Good point, I did not really have cryptographic RNGs in mind with my comment about streams. I guess if you want to use a different stream from a RNG for cryptographic purposes, it may be good practice to always reseed it. But is the point of CSPRNGs not to be completely unpredictable? Then it should not be possible to learn anything about the first RNG from the second one.

I don't agree that seeding a part of the state with 0's is perfectly valid. Xorshift for example would be significantly weakened by it. And while ISAAC has a complex initialization routine, I would not trust one initialized with a (large) number of zeros.

I have to take this all back. I tried implementing seed_from_u64 for IsaacRng, and its initialization routine seems like it can handle almost anything. For Xorshift I'm still investigating why it is statistically much weaker after generating 2^bits_in_integer numbers. But it seems to mix the integers of its state enough not to worry about initializing one with 0.

I never noticed reseed being called in the ReseedingRng and ThreadRng machinery, but maybe I missed something.  Instead, there is a separate Reseeder tool adding yet another layer of indirection.  I wrote https://github.com/rust-lang/rfcs/pull/2152#issuecomment-330565266 mostly to eliminate the indirection of Reseeder by requiring that seeds implement Rand.
Initially I felt the closure trick avoided Reseeder most simply, but @dhardy's pointed out that people do want to tweak the reseeding interval.  There are still simplifications if we require that  seeds implement Rand though, but give ReseedingRng a counter and/or upper bound.
I think ISAAC's internal counter only goes to 255, so you'd must modify it to go further and only use the low byte for ISAAC itself if you want to use it for this.
I'm neither for not against the name boost_entropy.  I picked it merely to avoid so many different things being called reseed.  augment_by_u64 etc work too.
As an aside, I'm now convinced Rust needs easier impl delegation because several decisions here would go "oh just use a wrapper type" if that were easy enough.

ISAAC has both a c counter that counts the number of blocks generated, and a cnt variable that counts how many of the result is not yet consumed. cnt only goes to 255. Combined with c it wraps around at 1tb.
If you trace the implementation in TreadRng all the way I found it calls reseed here (in the implementation used in the standard library).

@burdges I like your name boost_entropy. It makes it very clear what this function is for.

Cool.  add_entropy_u64 is also not excessively long.
If ISAAC and ChaCha already both have counters then exposing them through ReseedableRng sounds reasonable since a generic wrapper type could always add a counter to any Rngs that lacked them.  We could add a limit to the ReseedableRng trait too, so that ReseedingRng can default to just reseeding at that limit, and panic if the user supplied bound exceeds the trait's limit.
If we settle on u64 for the entropy boosting value, then I suppose absence of ReseedableRng might connote that proper usage requires rebuilding the whole Rng afresh.

I don't much like the idea of boost_entropy.  Perhaps 64-bits is enough new entropy that we don't have to worry, but in theory partial-reseeding allows entropy depletion attacks (if you know the previous state of a generator, then it gains a little entropy, and you have the new output, you can brute-force all possible values of the "entropy" until you recover the new output, then you know the state again). Of course, 2**64 combinations is a lot to brute force, but crypto PRNGs use more state than this because the attack is not inconceivable, especially if weaknesses in the algorithm are discovered. This is all theoretical since an attacker shouldn't be able to deduce the state in the first place, but IMO if we're going to boost entropy we might as well do it properly and reseed the entire thing (rather than partially reseed so that... we save a tiny bit of CPU time).
As I understand, all OSes now use strong CSPRNGs to "stretch" internal entropy to as many output bits as you like, so we don't have to "conserve entropy" (to prove the point, try copying 1GB from /dev/urandom — no problem). Sorry to shoot down your idea @burdges and @pitdicker but I just don't see any point to a boost_entropy API, or any real use in exposing the internal counter (where present) either.

@pitdicker isn't xorshift not exactly the best in the first place? It was suggested in the last thread that we can replace it with PCG as our default "fast, non-crypto" generator. Or perhaps some other slick new generator with better quality.

@Lokathor yes, but I don't see any harm discussing how to seed XorShiftRng. I think most small RNGs will be similar. I imagine for quite a few RNGs starting from a full-zero internal state doesn't work well, but if so the seeding algorithm should get around it somehow (e.g. by fixing some bits to a magic constant).

@lokathor
You are right, plain Xorshift is not great. But with an extra multiplication (with truncation) it performs very well. My implementation already easily passes Big Crush, with a state only half of that of the current Xorshift implementation. The 32-bit variant generates u32's at 3550 Mb/s, and the 64-bit variant generates u64's at 6200 Mb/s.
The advantage of Xorshift is that several of the well-known people in the world of RNGs have studied it. So its theory is well-known and trusted.
PCG seems great, but this is an RNG of a whole different category. Having the choice between both seems smart to me.

@pitdicker great. Modifying Xorshift sounds sensible but it's not technically Xorshift any more, so a new name might be in order. But this is off topic for this RFC (if you want to make a new RFC recommending changes to RNGs and where they should live, go ahead, otherwise I will eventually, after this one).

Can we have XorShiftMul?

Sure, but that is outside of what this RFC is about. This one is about picking our core traits to write implementations against. First we decide that, then we can write the implementations.

@dhardy You are right, it was not my intention to say much about Xorshift in this tread.
About seeding with an u64 I may have something that could be worth discussing.
Xorshift works best when about half of the bits in its state are ones. Over the course of the RNG's period it can come into a state where most of its bits are zero. Then the differences between one internal state and the next are small. This will quickly disappear, in 10~20 rounds, depending on its state size.
If the generator is initialized with mostly zero bits, the first couple of numbers numbers will appear less random. The number of rounds an RNG takes to get to the point about half of its bits are one depends for a large part on the size of its state.
Now I imagine it to be not all that uncommon for someone to quickly initialize a fast RNG like Xorshift for testing with a small number, like 1, 4 or 8. This means only a single bit is set. And then only a small number of results are consumed. Those first ~10 numbers will be less random.
Is this something we should guard against, by first running the generator 10 times to get past the initial low distribution of ones?
Or should seed_from_u64 just assume it is called with a good, really random integer?
I think we can just assume so. The scenario above is so careless, you deserve a little worse numbers :-)

That seems like a documentation issue. Remember that you can put a doc comment on a trait implementation and it will override the normal doc comment for the trait with that specific comment in the generates documentation for that type. If particular seed requirements exist that can be explained somewhere in the type's entry.
As a user, if I set a seed, I expect it to use that seed exactly. Even if the results are less optimal that way.

As a user, if I set a seed, I expect it to use that seed exactly. Even if the results are less optimal that way.

I agree partly. For just about all RNGs there will not be an direct mapping between a u64 and the internal state of the generator. Especially not if it has an initialization routine.
But the method of initialization should not depend on the value of the u64. That would introduce a bias.

Well, in my personal opinion, if a generator doesn't work well with mostly-zero state, seed_from_u64 should set the extra state to some "magic constant", and/or advance its state by a few iterations to get past the initial "not very random" region. Example: Jenkins small non-crypto PRNG sets 1/4 of its state to a magic constant and the rest to copies of the "seed". Of course, if we introduce new seeding functions for PRNGs they won't reproduce the same values as other implementations, but users should be able to seed via the "full seed" from_seed function for that.
Rationale (experience): some colleagues of mine used a sequence of seeds 1, 2, 3, ... to drive simulations. At the time I naively assumed someone there had looked into it and decided the RNG worked well enough with these seeds even though GSL docs seemed to suggest one should be careful with seeds. But many people don't read docs beyond the minimum required to "make things work". So: our job designing a library should really be to make it work well even when used naively by someone who doesn't bother reading the docs.
Hmm, which reminds me about the NonCryptoRng suggestion above. But I still think Rng would be hard to shoot yourself in the foot with; you'd probably have to write a generic function taking random secrets from a supplied rng, then have someone else give that a weak RNG like Xorshift or Mersenne Twister, and even then you're only vulnerable if you use a lot of output from that RNG and an attacker can get a block of that output, or the key was a constant or something. I mean, its usually obvious from the context what random numbers are needed for, and in any case our StdRng is at least moderately secure.

@dhardy So you worry about the same thing as I did, good :-).
I did not like the idea to fix part of the state with some magic constant. But now that I think a bit more about your comment, the solution is easy (and probably what you meant). Just xor the u64 seed (in case of Xorshift) with a fixed constant that has about half its bits set to one. The constant should not just set the high or low-order bits like 0x0000ffff, or be a simple pattern like 0xaaaaaaaaa. Both could easily match a what someone might manually choose for initialization. better is something like 0x2c2c57ed, which is a common constant for Xorshift* and LCGs.

What purpose does the seed_from_u64 function serve?  I could imagine value in adding entropy to an existing random number generator, but just starting a new one from a value much smaller than the seed sounds questionable.

Okay, I have changed my thoughts again about reseeding. I still think it can have an use, but there seems to be no regression for now if we just remove it all.
I created a pull request to see how ThreadRng would like like without the ReseedingRng abstraction.
Having it track when to reseed itself looks simpler to me than the current situation.  This is how reseed was currently implemented for IsaacRng, ChaChaRng and XorshiftRng anyway.

Sorry to shoot down your idea @burdges and @pitdicker but I just don't see any point to a boost_entropy API

I learned something new from your comment: entropy depletion attacks :-).
That was not really the direction I was thinking in for the situation where reseeding would help. Is an entropy depletion attack even a thing for PRNGs? Or purely something for 'the source of all computer random: the OS RNG'? (not really a question to discuss)
I think of occasionally scrambling the state of a generator more as some sort of 'defense in depth' kind of thing. Theoretically a RNG that is used for something as generic as the standard library should be very secure. Cryptographic quality or close. But there is always the incredibly small off-chance it will be broken. Now if its state is scrambled lets say every 32kb generated bytes, this would give an attack only a very short window.
So for ThreadRng occasionally reseeding seems sensible to me. But as it is implemented now, it works just as well without all the reseeding machinery.
One other argument against my own suggestion to reseed with only an u64: even if it makes sense, it is uncommon. Is there any RNG algorithm where the author gives advise on how to best do so? Most not anyway. That would mean Rand, and the implementers of every other RNG, would have to figure it out for themselves. Not something to recommend.

@burdges

What purpose does the seed_from_u64 function serve? I could imagine value in adding entropy to an existing random number generator

I am not sure what you ask. Or was it retorical? But we are discussing two things at the same time: initializing RNGs and reseeding them. Reseeding with only an u64 as a way 'to add entropy' is not great, as @dhardy commented.
Seeding with seed_from_u64 could be very useful for all less critical uses of RNGs, like testing, simulations and games.

What purpose does the seed_from_u64 function serve?

@burdges say you're making a simulator or game and want a reproducible "random" number generator. Having seed_from_u64 means you can pick any PRNG (or even use generic code), seed from a simple number, and not worry about "week seeds". It's just convenient, especially if you want to switch the PRNG. I like Mr Dicker's idea of XOR with a constant; hadn't thought of that myself.

Is there any reason SeedableRng and SeedFromRng can't be one trait?

I think removing ReseedingRng entirely fall afoul of @dhardy's criticism of my closure approach @pitdicker but you easily keep it while dropping the reseed function and do self.rng = <R as SeedableRng>::from_seed(..) instead.
We do not need SeedFromRng if SeedableRng uses an associated constant that requires Rand.

I used another trait because SeedableRng is templated and I imagined it could be implemented multiple times. If we have a single impl with associated type instead then I think they can be combined.

Not sure what you mean about my criticism @burdges. Shall we use gitter (also @pitdicker)?

After discussion with @pitdicker (see Gitter) I suggested the following. I'm not sure what N should be and @pitdicker doesn't like using an extra parameter.
pub trait StreamableRng: SeedableRng {
    fn from_seed_and_stream(seed: SeedableRng::Seed, stream: N) -> Self;
}

So that sets the seed and also the number stream for multi-stream RNGs?
I think it's a lot simpler to just have
trait SeedableRng<S> {
    fn from_seed(seed: S) -> Self;
}

And then multi-stream RNGs can provide more than one instance if they want to allow for setting the seed only (with a default stream) or seed and stream at once. Playground Example

@Lokathor I suppose multiple implementations like that works — although recent discussions indicated it would be better to use an associated type and not support multiple implementations, which is not compatible with your suggestion.
My thought is that an extension trait like I posted above is probably the best option (maybe also with a num_streams() -> usize function). If we use an extension trait, we don't force all seedable RNGs to support streams, and we can add the trait later if need be.

After the discussion on gitter I started thinking about what errors can occur, and how we expect user code to handle them. Of course I may have missed something, but this comment is what I've got until now.
I found three categories of possible OS errors:

Problems opening random device
The system does not have enough entropy
Interrupt by a signal handler

Available OS interfaces
Lets first look at the available interfaces and their documentation for several operating systems.

OS
interfaces (in order of preference)
documentation

Linux
getrandom (since 3.17, oktober 2015), /dev/urandom
kernel source, "Myths about /dev/urandom", introduction of getrandom

Android
(as Linux)

FreeBSD
kern.arandom, /dev/random (same as /dev/urandom)
[man page](https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4, rewrite 2014

OpenBSD
getentropy (since 5.6, november 2014). /dev/random

NetBSD
/dev/urandom
blocking is similar to Linux

Dragonfly BSD
/dev/random
behaves the same as /dev/urandom, has a higher quality PRNG

Solaris
getrandom (since 11.3, ) , urandom
introduction of getrandom

MacOS
SecRandomCopyBytes, /dev/urandom
there is no mention of SecRandomCopyBytes being available on OS X, but ring uses it

iOS
SecRandomCopyBytes

Windows
RtlGenRandom
see also this Firefox bug report. Documentation of the higher-level CryptGenRandom

Currently Rand is not always using the 'best' interface for every OS, but often just falls back to /dev/urandom.
Online a lot is said about the differences between /dev/random and /dev/urandom. See "Myths about /dev/urandom" and "How To Safely Generate A Random Number". Those articles set straight a lot of misconceptions, but do not apply to all OSes. The often suggested arc4random is an CSPRNG at the library level (occasionally reseeded), like the RNGs we wish to provide.
Possible classes of errors
Problems opening /dev/urandom
Until a few years ago, the standard way to get random numbers from the OS was on Unix to read from /dev/urandom. Wikipedia has a good article on the problems with reading from these pseudo-devices. "An attacker could interfere with a process's access to the pseudo-devices by opening all available file descriptors, or through a similar form of resource exhaustion attack. The use of these devices also interferes with privilege revocation. Unprivileged processes are often denied the ability to open and read files and devices, and the randomness devices are not even visible to chrooted processes." Maybe rm /dev/urandom can also be a reason why reading from the random device can fail, but I have not tested this.
The new, more reliable way to get random numbers is through a syscall. On Linux this is supported since 3.17 (oktober 2015). Rand uses the new interface if available. But because kernels from 10 years ago are still supported and used in production, we still need to handle the problems with /dev/urandom. OpenBSD was the first to support a special syscall, and also FreeBSD and Solaris supply one.
Conclusion: These errors can happen on systems that do not provide a syscall. If we are unable to open /dev/urandom, OsRng is essentially unavailable. Don't expect a retry or any other action to improve the situation.
Proposed solution

Sometimes an alternative to OsRng can be used. For example, if you only need a weak RNG, initialize one using the system time.
For libraries: bubble up the error. For applications it means informing the user, possibly with a panic.

If Rand would always panic when creating a new OsRng fails, it would not be possible to fall back to an alternative (if applicable). So Rand should have the ability to return a Result when creating a new OsRng.
The system does not have enough entropy
Entropy is a bit of a fuzzy concept. Especially the question whether you decrease entropy by using the kernels RNG. One thing is for sure: the kernel needs to collect entropy from several sources during boot (or read back from wat was collected before the last shutdown). When it has not collected enough yet, its internal PRNG is not yet properly seeded, and so random numbers are not yet available.
For most operating systems like Windows, OS X, common Linux Distributions, FreeBSD and OpenBSD this is not a problem, because they read back the entropy from before the last reboot. But it is a problem for VMs and for embedded devices, which are often running Linux. What followes is only applicable for Linux, NetBSD and Solaris, as other systems don't have this problem, or offer no choice.
If there is not yet enough entropy collected, there are several options open to the OS. What happens, depends on the OS, the interface, and the flags supplied:

block the process until enough entropy is collected
return an error (this error happens during read, not when opening the device)
return some not-so-random numbers

Blocking is available on all systems. On NetBSD and older versions of Linux and Solaris this takes some effort, because /dev/urandom will never block. First try to do a read from /dev/random with the O_NONBLOCK flag. As soon as that does not fail with the error EAGAIN, the OS RNG is initialized and we can rely on it being available. All the following reads should be done with /dev/urandom. With the modern syscalls and with the random device on other operating systems, blocking is the default. NetBSD recommends this method:

"Systems should be engineered to judiciously read at least once from /dev/random at boot before running any services that talk to the internet or otherwise require cryptography, in order to avoid generating keys predictably."

Getting an error is not always possible, because on some systems /dev/urandom always blocks (or is always seeded). On Linux and Solaris it is possible by setting the flag GRND_NONBLOCK on getrandom. On Linux, NetBSD and Solaris it can also be done by doing the first read on /dev/random, opened with O_NONBLOCK (similar to the method above). The advantage of using the random device over a syscall is, that it is possible to wait on it becoming available with poll. So even if we use the syscall, waiting can be done on the random device.
Getting some not-so-random numbers returned is only available with /dev/urandom on NetBSD, Linux and Solaris.
One final note: the reason not to use /dev/random on Linux always is that it can suddenly block after the initialization, when it for some reason estimates that its entropy is to low. In this /dev/random is very conservative, so it can be used to generate certificates, PGP keys, etc. That is way it is recommended to always use /dev/urandom for all normal uses.
Proposed solution
Currently Rand sometimes uses blocking, and sometimes not-so-random numbers. I would suggest to always give an error, and if this is not supported, to block. Using the syscall interface, and if not available the process described above.
Note: see also this discussion of the same problem in Python. The Python discussion shows blocking can easily take more than a minute, with the result that an unresponsive service can get killed by systemd.
To be fair, this is a problem that only a small number of application will encounter. The ones that will are probably services. I think it is safe to assume services are using an event loop and futures. OsRng or an other crate could provide a future like os_rng_initialized. It would have to read from getrandom or /dev/random in non-blocking mode, and if it fails poll on /dev/random. As soon as this future has resolved once, we can rely on OsRng to have enough entropy and never block again. This way the service can still do other things or at least be responsive while it has to wait on OsRng to become available.
An application that does not use an event loop and really wants to block, can simply open /dev/random itself and try to do a read on it.
The advantage of using error instead of blocking is that waiting with a future is possible. A second advantage is that it is possible to use a fall-back, like with "Problems opening /dev/urandom". If reading from the OsRng is preferred, but not critical for security, it may be better to fall back to a weaker source than to block for a minute or more. A final advantage of this method is that the error can only occur when creating the OsRng, never when reading from it with fill_bytes.
Interrupt by a signal handler
At least on Linux, NetBSD, Solaris, and maybe also on other OSes, the syscall and reading from a random device can fail with EINTR. The read is interrupted because a signal like Ctrl+C is received (see this blog post: "EINTR and What It Is Good For". The common advise on how to handle it is to just retry.
EINTR Is useful for applications that have installed a signal handler, and need to get to the point in their code that checks for the signal and does clean-up etc. Otherwise the application would remain stuck waiting on the kernel to fill a buffer with random bytes for seconds or more time. If one was doing multi-second reads on the OsRng, returning a Result with ErrorKind::Interrupted or similar would be appropriate.
One scenario where this could happen is when we block on the OS RNG until it has enough entropy. But if we follow the proposal in the previous section to never block, this is not a problem for us.
Rand's fill_bytes interface can read bytes from OsRng to a memory buffer. On my system it can fill 1 GiB in 3 seconds. It seems to me that only from amounts like this it makes sense to pass on the interrupt.
When doing a short read (like the read to initialize a RNG), it is best to just retry. And possibly only retry for the number of bytes not yet returned.
The scenario of reading from the OS RNG into a huge gigabyte+ vector in memory seems a bit far-fetched to me. If you do things like that, expect not everything to work smoothly. So just retrying on EINTR is best for fill_bytes. Combined with the steps from "The system does not have enough entropy", fill_bytes can never fail and so does not have to return a Result.
Other uses of Result
Using a RNG beyond its maximum
All simple RNGs have a period, after which it loops. It may be possible to use some RNGs for as many times as their period allows. But a common advise is to not use more rounds than the square root of a generators period.
Similarly, cryptographic RNGs may have a amount for which they are considered safe. @burdges mentions ChaCha, where the counter can wrap (Wikipedia).
These RNGs could make use of a fill_bytes function that returns a Result to indicate they have reached their maximum. But do we really assume that the callers of fill_bytes are all going to look at the error, reseed the RNG, and try again?
Of course, the best solution is to just use a RNG that can generate far, far more numbers than you ever need to consume. Then again, for many uses it is no practical problem if an RNG loops. Most have a usable period of 2^64 or more. That is 65536 exabyte of generated bytes!
If you still want to use a RNG that has a period that me be to small, I think it is best to combine it with a wrapper like the current ReseedingRng. The wrapper can automatically reseed the RNG to much numbers have been consumed, without the calling code having to deal with the result.
RNGs outside the process
@burdges suggested RNGs outside the process, like Pulsar. It provides random numbers generated by thousands of participants, with the goal of providing publicly-verifiable, unpredictable, and unbiasable randomness.
Using an external service like this as a source for randomness has the potential to fail with IO errors. But as @burdges notes, do we really expect one to implement something like this using Rands Rng traits? It does not really seem like something we should design for.
Hardware RNGs
Hardware generators could also fail, for various reasons. I have not really looked into them.
As @dhardy noted most code won't use one directly. It would probably be used through a wrapper that also provides a fall-back generator in case the hardware RNG is unavailable.
Like the OS RNG a hardware RNG could simply be unavailable, and fail during initialization. It may also fail at some point while it is used (I imagine it like pulling out the usb cable :-) ). It is possible to pass on the error by returning a result from fill_bytes.
This seems to me the only valid reason to have fill_bytes return a result. But returning a result is only one way to pass on an error. But the implementation could also provide some still_ok function, that gets checked by the wrapper type. It seems to me we should not make the Rand harder to use for everyone just to make this use case a very little bit cleaner.
Conclusions for the APIs
I propose we add two methods that return a result for OsRng, and to not have any other methods in the core traits that return a result.
So instead of
    fn try_fill(&mut self, dest: &mut [u8]) -> Result<(), Error>;

use
    fn fill_bytes(&mut self, dest: &mut [u8]);

The implementation of new for OsRng remains the same:
impl OsRng {
    pub fn new() -> Result<OsRng>;
}

When creating a new RNG, I would like to propose two variants. If the goal is to get a quick not-security-critical RNG, use the OsRng if available, and initialize with seed_from_u64 and nanoseconds of the system time as a fall-back. This has a resolution of about 20 bits, but it can be better than having no generator at all.
If the goal is to create a secure RNG, it really has to be properly initialized. So then always try_new should be used, that returns a result.
#[cfg(feature="std")]
pub trait NewSeeded: Sized {
    /// Creates a new instance, automatically seeded via `OsRng`.
    /// If `OsRng` is unavailable the RNG is initialized using a weaker source:
    /// nanoseconds of the systemtime.
    /// The `OsRng` can be unavailable if the OS does not provide a better
    /// interface than `/dev/urandom`, and there are no more file descriptors
    /// available, or if we have no permission to access it.
    fn new() -> Self;
    /// Creates a new instance, automatically seeded via `OsRng`.
    /// If `OsRng` is unavailable an error is returned. This is recommended for
    /// cryptographic RNGs.
    fn try_new() -> Result<Self>;
}

@pitdicker
Thank you for your review! One nitpick: I don't quite get why in your conclusion you exclude solution to include both try_fill and fill simultaneously, as I've mentioned earlier I think it's a commonly used solution across Rust ecosystem and in the std in particular. As for still_ok I don't think it's a good solution, yes, as alternative we could add method to check if previous call to fill (or next_*) was successful, but I personally strongly dislike this approach, as it's seriously error-prone.
@nagisa
What is your opinion on using associated error type instead of explicit type defined in the rand_core crate? (well, seems the name got fixed without any discussion right after publishing this RFC...)

@nagisa @newpavlov Would you like to discuss this on gitter?

well, seems the name got fixed without any discussion right after publishing this RFC...

The fact that the crate is being squatted on has no bearing on it being fixed whatsoever.

What is your opinion on using associated error type instead of explicit type defined in the rand_core crate?

I haven’t really tried to play with either approach yet, so my opinion not very strong, but I sort of share the concern that it would make using Rng tad a bit harder. And possibly cause library authors to unintentionally limit the choice of Rngs.
For example, it is fairly trivial to write such a function:
fn dobananas<R>(r: R) -> Result<_, SomeOtherError>
where R: Rng<Error=SomeConcereteError>
{
    // ...
}

What is not obvious, that it pretty much limits this function to specifically the Rngs which use that SomeConcreteType specifically. And it is also not obvious that the correct way would be to write one of these instead:
fn dobananas<E, R>(r: R) -> Result<_, SomeOtherError>
where E: Into<SomeOtherError>, R: Rng<Error=E>
{
    // ...
}
fn dopeaches<RngE, R>(r: R) -> Result<_, SomeOtherError<RngE>>
where R: Rng<Error=RngE>
{
    // ...
}

And yet this still may limit the use of Rngs to specifically Rngs which implement Into<SomeOtherError> (which could be a problem if SomeOtherError is not, say, std::io::Error). And it won’t work for conversions like SomeConcreteError -> std::io::Error -> SomeOtherError.
With that in mind, I think that a simple no-fluff enum error type common to all Rngs might be better, but I really am not sure. Both have their benefits.

@naglsa  There were concerns that quantifying over the associated Error type became too burdensome for users who simply want a PRNG for numerical purposes.  Also, an associated Error type makes it easier to use CSPRNGs incorrectly too, i.e. try_fill(&mut secretkey).unwrap(); is likely secure, while try_fill(&mut secretkey).unwrap_or(()); is always insecure.
We imagined that anyone who wants to deal with errors could use another trait, which unfortunately people call CryptoRng, although names like ExtRng correspond better.  We did not plan to bubble the error from this CryptoRng/ExtRng trait up through the ReseedingRng machinery because we imagined those errors should be representative of system misconfiguration.
I mentioned Pulsar because it's a counter example to this last statement, but..  If you use pulsar, then you presumably need that distributed randomness property to produce determinism properties, so you must explicitly consume pulsar output to seed a ChaCha or whatever anyways.
Also, we did not mind ChaChaRng panicing when you hit its limit because the limit is huge, assuming user data cannot be fed into its seek method.
In short, we felt errors from the Rngs we understood really corresponded to panics as opposed to errors that one could handle locally.
I've a side question for you too : Is it enough to go with an associated Error type in you case?  We could maybe support Rngs that operate asynchronously with a Result ATC, right?  To me, this sounds excessively general, but you're the only one here actually working with a hardware PRNG.
trait AsyncExtRng {
    type Result<T>;
    fn try_fill_bytes(buf: &mut [u8]) -> Result<()>;
    fn try_next_u64() -> Result<u64>;
}

@nagisa
You don't have to specify associated type if you don't need to fix it for something:
fn foo<R: Rng>(r: &mut R) -> Result<(), SomeOtherError> {
    r.try_fill().map_err(|_| SomeOtherError)
}

fn bar<R: Rng>(r: &mut R) -> Result<(), R::Error> {
    r.try_fill()
}

Especially if you use only infallible methods. So I don't think associated error type should be a problem in practice.

The fact that the crate is being squatted on has no bearing on it being fixed whatsoever.

I was talking about hyphen vs underscore discussion. AFAIK it's currently impossible to change crate name from rand_core to rand-core.
@burdges
We could go with TryRng: Rng trait (don't think that ExtRng is an appropriate name here), which will include try_* methods and associated error type, in some way it will be an equivalent solution. It's a design decision to keep all methods in one trait on split between two traits. Personally I am fine with both approaches.
As a pro argument for splitting: we could add TryRng in rand_core v 1.1 as a backwards compatible extension after stabilization of default associated type and never_type.

@burdges

I've a side question for you too : Is it enough to go with an associated Error type in you case?

For my personal usecases even a
#[non_exhaustive]
enum Error {
    EntropyExhausted,
    // Some other common errors
    Other,
}

is plenty. To me EntropyExhausted is the only necessary error variant and Other can subsume cases like hardware being unplugged or discharging or catching fire just fine. Usually because the code which produces the Rng can handle the Other variant by adding the necessary information itself:
let mut rng = HardwareRng::new()?;
match run_app(rng) {
    Err(errors::RngError(rand::Error::Other))  => Err("HardwareRng failed to produce random data for some reason, do check")?;
    // ...
}

at which point the user will be prompted to check their hardware for issues, whatever they may be.
Associated type would be general enough as well, but I’m wary of it for reasons I described in my previous comment.

We could maybe support Rngs that operate asynchronously with a Result ATC, right? To me, this sounds excessively general, but you're the only one here actually working with a hardware PRNG.

Asynchronous RNG seems like a plausible extension for the tokio ecosystem (think: tokio-rand). I don’t think there’s much point in discussing it for rand_-core or even rand crates. People using OS /dev interfaces (especially the /dev/random) might be the larger target audience for such a crate compared to people using hardware generators.
@newpavlov

You don't have to specify associated type if you don't need to fix it for something:

Sadly, that doesn’t work very well if you want to use proper error propagation.

For OsRng it should also include:
#[non_exhaustive]
enum Error {
    EntropyExhausted,
    NotAvailable,
    NetYetSeeded,
    // Some other common errors
    Other,
}

(the names are probably terrible)

Just read up on your latest comments. Thanks all, especially @pitdicker for the detailed review!
Before getting to the error type, if we have try_* functions, then:

Are try_next_u* actually useful? I don't want to have to deal with errors bubbling up through the distribution/conversion code and I don't think most users want that, so who else would use it?
How does fill_bytes handle a case where try_fill returns an error? It seems to me like the only safe option is to panic. Maybe some implementations could add code to make it retry or block for a limited time. If we have an enum like above detailing the categories of error then possibly there could be standard code doing this for all implementations, if fill_bytes has a default implementation using try_fill.

Regarding the error type, thanks @nagisa for backing my view that a single global type is much easier to work with (lets also consider less advanced Rust coders who want to use generics but aren't as adapt as @newpavlov).
The Error enum just above may be sufficient. Looked at from how errors should be handled, we need:

a way to request reseeding (EntropyExhausted) [not personally convinced this is necessary, but we can go with it]
a way to report permanent unavailability (NotAvailable)
a way to request wait-and-retry (NotYetSeeded)
a way to request immediate retry a limited number of times (e.g. for RDRAND, as noted on gitter)
something to coerce other errors to when unsure? (Other)

I guess this should be enough, but it doesn't allow any details / note of error source. Including a &'static str payload for each enum variant would allow this, at I think very little cost — it doesn't allow proper propagation of e.g. std::io::Error but hopefully code can convert that on a case-by-case basis instead of simply forwarding (e.g. report NotAvailable instead of ErrorKind::NotFound).
I like @pitdicker's modification to NewSeeded offering a fallback. Not 100% sure on it; e.g. users could mis-use new when they should be using try_new; maybe new to new_with_fallback or new_weak?

I like your new_with_fallback suggestion. It is better to make the default new method be the more secure choice.

While I think we should just retry en EINTR for OsRng, @newpavlov makes the case that some user may want to be informed of an interrupt. So OsRng::fill_bytes could retry and remain infallible, and OsRng::fill_bytes could return an error in this case.
For other RNGs it can also make sense to return an error on interrupt, for example ReadRng.
Can we add an extra variant to the Error enum, Interrupted? This would not be the same as 'request immediate retry', as this has a different cause, and maybe one wants to handle it differently.

I'm still not sure that we should expose ReadRng; a cut-down version can live in the os module quite happily.
As @pitdicker pointed out earlier, for multi-second reads handling an interrupt properly makes sense, but it's unlikely rand will need to do multi-second reads from OsRng. What was @newpavlov's argument again?
Not that I have anything against adding extra variants to Error; it seems we have it and there's basically no cost involved.

Since it came up, which would you prefer?

rand-core (thumb up)
rand_core (thumb down)

Please vote with a thumb (+1 / -1).

I kinda hate to bring it up right now, but a default next_u64 implementation that relies on bit-shifting two u32 values into place is actually potentially very unsound the more you think about it. Not in a memory sense like rust normally cares about, but in the sense that your results will almost certainly not actually be uniform. The u64 sequence will (probably) loop before having produced all possible u64 values. The period of the u64 sequence will obviously be exactly half the period of the u32 sequence, and if that's less than all the u64 values you obviously won't end up seeing all the u64 values. Even if the period of the u64 sequence ends up being big enough to potentially produce all the u64 values you're it might not actually do it based on the generator (your generator would have to have 2-dimensional equidistribution).
So, I don't know if we care about that whole deal. It is, in some sense, not even a problem you care about until your sequence starts looping. If the u32 generator's base period is 2^64, the u64 sequence would still be a period of 2^63, and that's quite a lot of u64 values after all.

There is no relationship between output size and period.  If you sample a chacha stream 1 bit at a time the period remains the counter width for your chacha variant, like 2^70 or whatever.  There are PRNGs where the period depends upon the seed and is unknowable in practice, but it still has nothing to do with the output size.

The period of the generator itself doesn't change. I'm saying that the period of the "final" output that you get after you combine more than one output is necessarily less than the period of the initial generator if you're using a number of generator uses equal to a factor of the generator's period (in this case: 2 is a factor of 2^64). It will use up an evenly dividing portion of the raw generator stream and then loop around and start at the same portion of the generator's stream that it started at before.
Imagine, just for the sake of example, that the generator produces exactly two u32 and then loops.
// u32 stream, 2 elements
0xABCD1234, 0x55558888, loop

Now imagine that we want u64 values, so we grab two u32 values and bit-shift them together into a single u64.
// u64 stream, 1 element
0xABCD123455558888, loop

The period of the u64 stream is half the size. That is what I was saying.
Alternately, if you grab an amount of the stream that doesn't evenly divide by the amount that you're using at a time then the result stream will have length equal to the input stream.
// alternate u32 stream, 3 elements
0x11112222, 0x33334444, 0x55556666, loop

// alternate u64 stream, 3 elements
0x1111222233334444, 0x5555666611112222, 0x3333444455556666, loop

And even if our result stream is the minimum period required to cover all u64 values (2^64) it doesn't necessarily actually produce u32 values such that all (low_bits, high_bits) combinations appear an equal number of times and you end up seeing all u64 values an equal number of times. If the starting generator's period is 2^70 and you eat it up twice as fast you'll use it all and loop at 2^69, but by then you'll have seen some of the u64 values more than others for sure: 2^(64*2) > 2^69 > 2^(64*1)
So, basically, the next_u64 implementation that is correct for a given 32-bit generator either needs to be hand-selected so that the generator uses u32 values at the right speed and it all loops in phase correctly, or it can't really be constructed at all (for some generators).

My previous reply was unclear so I deleted it to write this, but sorry if you're getting the update emails.
Here's a clear and better re-wording of it: 32-bit generators with periods of less than 2^64 are unfit to have a next_u64 method. If the generator is good and uniform with a period of 2^33 (eg: each u32 appears in the sequence twice), it still won't produce all possible u64 values if you run it twice and merge the results. The period of the 32-bit generator must be at least 2^64 for it to be 2-dimensionally equidistributed.

@Lokathor
Generators with a period that can be encountered in practice aren't actually fit for general-purpose use anyway, even if you only pull single bits off them. Reasonable PRNGs should generate a close-to-uniform distribution on pairs (and triples etc.) when distributed over the generator's seed.

@Lokathor does have one point: the period is usually measured in terms of how many values of a specified size can be generated, so is not directly comparable in terms of bits/bytes. Of course though if you half the period you go from 2^x to 2^(x-1), and if this period is too small then the full one (2^x) likely is as well. Most generators do not try to exactly reproduce all representable values; this is not truely random (to take an extreme example: if a 1-bit generator was supposed to cycle all bits, it would be 0, 1, 0, 1, 0, 1, ... — fully predictable, unlike e.g. a coin-toss).

I think any PRNG with a known period should error or panic when it reaches the period, not cycle.  We do not expect to ever encounter this except through abusing seekable PRNGs like ChaCha, or using particularly bad PRNGs.

Do you? I don't; for many PRNGs detecting a cycle is hard (especially with seeking). What do you mean by "with a known period" — are you including e.g. MT with its 2^19937-1 period? Where would you define the "end" — when the initial state is recovered or when some arbitrary state in the sequence is reached? For ChaCha you have a counter that can be used, but again, you don't necessarily start at zero (it's a 128-bit counter IIRC, part of which may be used for a nonce, or some extra seed); when should ChaCha error — when all bits go to zero, or just the low 32 or 64 bits? (And what if someone wants to use 64-bit nonce and 64-bit counter instead of the 96/32-bit split to get over the 256GB limit — then the low 32-bit cycle detection would be a problem.)

Your generator could record an entire extra copy of the initial state that it doesn't modify, then each time it checks if the state it just arrived at matches the state it started with and then mark itself as exhausted. Seems poor though. I certainly would not want that as the default operation for any generator I ever use.

A period of 2^33 is very hypothetical. I am not aware of any PRNG with a period less than 2^60.
2^60 ~= 10^18. The fastest RNG can generate exactly 1.000.000 numbers/second on my machine (probably memory bound or something). So to max out a period requires 10^12 seconds (e.g. an impossibly large number of years on current hardware).
But the main purpose of a large period is not to prevent cycles. It is to make sure that when you pick some random initial state, you probably won't end up in the same range as some other generator of the same type.
Now statistics is not my strongest side, but I believe it works something like this:
p = period
u = expected amound used
n = number of generators

chance ~= 1-e^((-n^2)/(2*p/u))

Take for example a generator with a period p=2^64. And lets pick some arbitrary expected amount of used rounds, u=2^32 (16 GiB or 32 GiB, takes about a minute to generate). It then takes about n=2^16 initializations to have a 50% chance of repeating part of an already used stream. A 50% chance is way to high, lets try 1 in a million. Then we could only need to do 100 initializations to reach that chance.
That is why RNGs with a period of 2^64 are the bare minimum for any practical purpose. You could argue they are to small.
Lets look at a period p=2^128. And lets use an upper limit of u=2^48 for the expected amount of used rounds, which equals about 1000 TiB, about 9 years of continues generating on my machine. It then takes about n=2^32 random initializations (and running 9 years) to have a chance of 1 in a million to repeat part of an already used stream. So a period of 128 bits should be enough for any practical purpose.
PractRand calls a period of 2^128 "good enough for any use today", and periods of 2^256 "future-proof". I think that is overly cautious, and would call 2^96 "good enough" and 2^128 future-proof".
Jumping a generator a fixed amount instead of initializing a new random state could be a way to make better use of the available period. Instead of depending on chance to get a new generator with a different state, jumping makes sure every new generator has a new window of its own. But it requires discipline to base every new generator on the previous one.
While I previously thought: "wow, jumping is a great way of initializing a generator! It would make small periods usable!" It turned out to be as slow or slower than initializing from the OS. And to do it right, initialization would need cross-tread synchronisation.
Because this was the only real use I could think of for jumping around in a generators period, implementing fixed jumps as a way to add streams to a generator seems not useful to me anymore.
tl;dr:
We do not have to worry about cycling a RNG. But any RNG should have a period of 2^96 or preferably 2^128 to decrease the change to have two generators produce an overlapping stream.

Any standard ChaCha clearly defines the counter and nonce portion, so the counter determines when it definitely cycles, and it should error or panic instead of wrapping the counter.  Anyone writing a non-standard ChaCha PRNG can issue the error when appropriate.  There is obviously no way to detect cycling caused by the internal state returning to a previous point, but the internal state should be big enough to make the chances vanishingly small.
Any ChaCha except XChaCha can change the nonce as fast as changing the offset, btw.
As an aside, I've used seeking to provide deterministic series of random numbers of bounded length before, but only as byte streams, not using the Rng trait.  I strictly constrained the substreams with accessor functions containing appropriate asserts and fork off separate ChaChas when using Ziggurat.  If you want cheap forkable streams then you might adjust the nonce on a ChaCha using heap addressing, maybe taking the depth to be the low 6 bits of the nonce.  You'd navigate the nonces with left, right, and up functions plus clone.  If you want more depth, then you might use IETF ChaCha which offers a 128 bit nonce but only a 32 bit counter.  I'd consider doing this if I needed Ziggurat more, but avoiding the rand traits until needed improved readability too.

Any standard ChaCha clearly defines the counter and nonce portion, so the counter determines when it definitely cycles

@burdges Take a look at the code; the only bit which species which bits are nonce is the documentation of set_counter: this code allows the user to decide which portion is nonce. And no, it's not a cycle (by the usual definition) when the counter-part wraps to zero, because the nonce-part gets incremented too. The only real issue is that if the generator were used again with the same seed but different nonce, and the new nonce happened to be the old nonce + 1, part of the sequence would overlap. But if the user re-uses the same state they already have to avoid using the old nonce too; probably the user should use a new seed for a new encryption stream in any case, in which case it doesn't matter if all 2^128 blocks of 2^9 bytes (2^137 bits) get used.
So the only problem with ChaCha is if multiple nonces get used with the same seed; to have any chance of exceeding the counter part at least 96-bits must be assigned to the nonce. If a second nonce were picked at random, there would be a 2-in-2^96 (1 in 2^95 or approx 4*10^28) chance of picking an overlapping nonce. If many nonces are picked from the same stream, the base problem is essentially a birthday-paradox problem; the modified one with extra nonces used due to overrunning the initial stream is essentially the same but with a small reduction in the nonces which can be used before a fixed probability of clash (like 1 in a million) is reached. Can't really see the problem myself; ideally one shouldn't use multiple nonces from the same stream anyway I believe.

It's interesting that ChaChaRng does not correspond to any standardized ChaCha, but okay.  Implementations I've looked at for standardized ChaCha all have either 32 bit or 64 bits counters, and they error instead of overflowing into the nonce, but not sure what DJB's paper says.
We previously discussed exposing a counter in the ReseedableRng trait, probably a u64, but maybe that does not impact this discussion.

@burdges When you talk about ChaCha standards and implementations, do you mean those that use ChaCha as a stream cipher or that use it as an RNG? For a stream cipher it makes sense to error. But for an RNG it feels less so to me.

@burdges ok... I see that this cipher implementation assumes 64-bit nonce and neither increments that nor errors on overrun, but just says the following:

/* stopping at 2^70 bytes per nonce is user's responsibility */

FYI I enabled GitHub issues on my rand fork to allow threaded discussion of issues. Feel free to create more; initial focus is to get this RFC finished (but others are allowed).

https://github.com/rust-lang-nursery/rand/issues/180, admittedly, a case where failure seems to be in Rng::new() and unrelated to the Rng trait, it still shows off that people are willing, and have a reason to, work around failures in Rngs.
Also consider a similar problem with allocations, which panic on OOM and are a major pain point for certain kinds of libraries/programs.

To be fair though the problems described there are (I think) all init problems, something OsRng::new() should report.
@nagisa what's your point with regard to allocations? Usually the story is die-on-OOM and the Linux kernel doesn't even report OOM by default, it just kills stuff. How are you supposed to handle that?

The point of both my examples is that (a vocal minority of) people are increasingly interested in ability to handle errors, even if they are unlikely to happen (or only happen in uncommon configurations).
I’m re-reading the updated RFC right now.

Uh, I'm updating the RFC right now...
The issues shows some of the latest stuff, as well as this PR (first comment is out of date).

cc @briansmith

@aturon no, we're not really working from the RFCs now. Some of the plans are the same, some have changed; we're getting feedback via PRs now which has the advantage of more detail but perhaps the disadvantage of less audience.
Since rand is outside the core library anyway I'm not sure these RFCs are really in the right place anyway. At some point there may be discussion of whether std will use rand instead of its internal copy, but that's a different issue (unless it has ramifications on how rand should be structured, in which case please weigh in).

@dhardy OK, that's pretty much as I had assumed, and is totally fine. It's wonderful to see rand making as much progress as it has!
For the time being, I'm going to close out these RFCs. Those interested in rand's development can follow along on its repo.


Add resources

It would be nice if it is possible to create an interface for all resources, like this
public interface IMyResource : IResource {  [ResourceLocation("location-uri (file, pack, http etc)")]  BitmapSource Logo {get; } }
The framework should handle the converting between files / streams (bytes) to the type, the supported types should be extensible. Bitmap/BitmapSource,xml etc.
It should be able to handle monitor file changes, rereading (http), maybe have fallback, use the Dapplo.InterfaceImpl extensions for INotifyPropertyChanged etc.
It should find resource on the file system, http(s) (use Dapplo.HttpExtensions), pack (internal) etc
Maybe this could also be extensible.
Behaviour could be changeable, e.g. a Bitmap could be "singleton" or cloned at every get. (help with dispose?)
In the end, it should simplify the usage of resources, make refactoring of both the location or type of the resource and the code easier.

Also add optional / mandatory so we can either get an exception or ignore the missing resources.


How to generate sub module in a module?

Hi @gravitano,
I'm using your plugin to create a modular app.
I want to divide my Module folder in two folders like "admin" and "client" and than their particular modules in that folders,
So can you suggest me how can i do that.
Thanks

Hi @Priyank57, currently this package is not supporting sub module feature.

@gravitano Do you plan to implement this?


Add docs for new Validator methods

@MrThreepwood @thibaultmeyer could either of you want to help with this?

Docs are here: https://github.com/javalin/javalin.github.io/blob/master/pages/docs/docs.md#validation

Yeah I can grab those. I noticed that there aren't any docs for the body validator currently. I was hoping to just move those to say they exist on all validators since the new validation methods were actually just moved from that class.

@MrThreepwood thank you, I appreciate it! I guess the BodyValidator just adds one argument to one method to specify the field, could just mention that?

Sure. In the long run I think it'd be good to have the same option on the base validator. The problem is Javalin allows a custom converter (meaning a param (header, form, query) can be a complex object. So I don't think the body validator and regular validator should really have any differences. People may not use the option for most simple parameter types, but if they need it it would be nice to have it.
At that point the body validator is an exact copy of the regular validator that it extends though. For backward compatability you probably wouldn't want to remove the body validator, but I suppose it could be depricated? That's a different issue though I suppose.

I believe you already fixed this one @MrThreepwood, please reopen if I'm mistaken.


Lost People

What about the people who have been lost? Can we provide an option at rescue centers or others to upload image and details of the lost people?

May for issues that cannot be handled now, report them in a group like - https://t.me/RescueKerala


Like Dislike Increase Decrease Problem

Maybe after a crash, but like dislike do not increase factor.

Bug is fixed and factor changes accordingly with thumbs up or down action.


Fix version checking for Debian repo for future versions.

Hello,
With this solution, new versions of Node will be covered, assuming that the repo naming convention sticks.
What do you think @wolfeidau? Does this fix #19 ?

@mtpereira This looks great, would be nice if you based it on master rather than my branch? So I can merge it there.
Cheers.

Hello,
Ok, I'll fix those things.
My thinking on opening a PR to your feature branch was that you could merge it your branch, adapt as you see fit and then carry on with merging the original PR.
As for the variable, I always feel safer my prepending every var name with the name of the role, in order to avoid collisions.
Thank you.


Send reminder emails before season start

Free Agents shall receive Emails to remind them that they signed up shortly before FAT assignment happens.

[ ] Write a text (or delegate that to editors)
[ ] Create email component that sends these mails
[ ] Figure out a date
[ ] Add email sending to schedule (or do manually)
[ ] also think about reminders for captains

@Fabian-Sommer I guess  you can set that to Season 6 as you've done that manually now

We can continue doing this manually


Update third-party dependencies

If the new endpoint infrastructure capabilities add new dependencies, we need to document those and get Legal approval.

Informed Zak of the new dependencies. Updated the wiki and got approval!


Upgrade stack

I wanted to upgrade only babel but everything else was broken so I
upgraded babel, webpack, eslint and karma.
Disabled a lot of eslint rules to not change existing code. Maybe it's
better to migrate to prettier later.
This changes will unblock me from providing smaller output.

/cc @chenglou

We need to rerun travis

Friendly ping @chenglou

Thanks for the ping. To be clear, is there a user-facing change here? Or just for us devs?

@chenglou This one only for devs.

Bundle is slightly changed with new versions but I don't think there's anything significant.

@chenglou Tests are passed.

If there's no user-facing impact then sure. Thanks!


The image is inverted and the color is not normal.

My operate system: Ubuntun 16.04 cuda9.0 zed_sdk2.8.
when I open ZED Explorer ,I recieved the following image ：

how should to solve this problem ？

this is my cuda and nvdia

This comes from a non compatible OpenGL driver version (GLSL error).
Make sure that opengl driver (mesa) are installed or during NVIDIA driver installation, make sure that it installs the opengl library.


Controller should watch KubeFedConfig for updates

What would you like to be added:
The controller manager should watch the KubeFedConfig that configures it and assume the latest configuration as that resource is updated.
Why is this needed:
Without this feature, it requires restarting the controllers to update to a new configuration, which isn't desirable.

/kind feature

/assign


Add code-analysis pipeline with Coverity scan

Coverity scan completed successfully. Build was marked as 'failed' because of high+medium warnings.
https://i.ci.build.ge.com/bjmjek1k/ci/blue/organizations/jenkins/UAA%2FAnalysis/detail/coverityScan/3/pipeline

Coverity scan completed successfully. Build was marked as 'failed' because of high+medium warnings.
https://i.ci.build.ge.com/bjmjek1k/ci/blue/organizations/jenkins/UAA%2FAnalysis/detail/coverityScan/3/pipeline


Fix prop-context update tearing

Closes #259.
This PR tries to fix the update tearing behavior I discovered and reported in #259 based on a solution that my team has been discussing. I introduced a fairly small and robust test that is currently failing to indicate the problem with our current state and the quick-fix solutions to this problem.
Context values are no longer based on bindings and now instead use a small cell that contains a value and an update signal.
Providers now update context values in two passes:

In willUpdate, the provider updates the value of the context entry but do not fire any signals. This should cause downstream consumers to be able to immediately read the new value on their next render. Their next render will occur immediately unless an intermediate component implements shouldUpdate.
In didUpdate, the provider fires the signal portion of the context entry. This will notify any consumers.

Consumers are now a little dumber and simpler. They no longer track the current context value in state, but instead track the last value they were updated with. When an update signal is received from their corresponding provider's didUpdate hook, consumers now compare the new value with the value they were last updated with, stored in their didUpdate hook. If these values differ, we can assume that there was a component between the consumer and provider that returned false to shouldUpdate, and trigger an update.
I dramatically increased the documentation around affected code to make these kinds of issues more clear to us in the future.
TODO

[x] Failing test and bug explanation in source code
[x] Actually fix behavior

Checklist before submitting:

~Added entry to CHANGELOG.md~

We didn't make a release with the broken context API, so this should roll up under just introducing this feature.

[x] Added/updated relevant tests
~Added/updated documentation~

No user-visible changes because this feature has not been released yet.

This looks good! I think it solves it pretty nicely. I had a nagging feeling that somehow the Consumer should be expressing its render deduplication via shouldUpdate, but I'm not sure if that would work any better than this as it is.

This looks good to me. I like this solution a lot.

Woops, forgot to mark as ready to review.


Bug: Inconsistent CLI flags style: --no-tests requires an equal sign, all others use space

Description of the issue
Description:
Steps to reproduce:

Intuitively try to use the new --no-tests flag, e.g. --profile ci --no-tests warn.

Expected outcome
--no-tests warn should work just as all the many other nextest flags with values, all of which use a space between flag and value.
Actual result
It fails, with --no-tests requiring =, rather than a space.
Nextest version
cargo-nextest 0.9.85 (d5f93f64f 2024-11-26)
release: 0.9.85
commit-hash: d5f93f64faf6b1d1d425dce52019c14757c7b082
commit-date: 2024-11-26
host: x86_64-unknown-linux-gnu

Additional context
Initially mentioned in https://github.com/nextest-rs/nextest/discussions/1646#discussioncomment-11436543.

Thanks for the report! I was wondering if/when someone would notice :)
So a recurring issue for nextest users has been mixing up test name filters and arguments to options. For example, imagine someone specifies --no-tests warn in a script, and a few months later someone changes it to --no-tests fail. But by accident, warn is left in afterwards, so it becomes --no-tests fail warn. All of a sudden, warn will start being interpreted as a test name filter, which is a bit spooky. (This sounds far-fetched, I know, but something very similar to this actually happened once around the --profile option.)
With --no-tests=warn, this has no chance of happening.
At some point I came to the belief that requiring options to be specified with equal signs will end up being less confusing overall -- in hindsight, I think nextest should have started this way, but it's too late to change that now.
So, at that point, it's a matter of consistency with existing options vs not making the confusion worse. I was hoping to lean into the latter, but I definitely see the argument for the former.
What do you think?

I've been thinking about this more -- I wonder if the default being fail mitigates the harm sufficiently -- the most egregious cases would be caught right away. Disambiguating between options and arguments feels like such a hard problem.


Make the rapid api UI workable for Login and Data upload

Hey team! Please add your planning poker estimate with Zenhub @bogdan-mania-moj @hemeshpatel-moj @LavMatt @murdo-moj

Please add your planning poker estimate with Zenhub @PriyaBasker23


V2.1-Resolved issues related to print after SignIn,private item not populating URL,display legend in print preview,missing space in NLS file

Resolved following GitHub issues:
#102-Comment the codebase
#138-localized the strings listed in the code in the description
#150-Flickr Widget is not working Briefing Book (released and current version)
#171-Some tags causes load failure for all books in the application gallery
#194-If Summary Item Text of a webmap is empty.
#198-Print button not available when user is now logged in
#199-UI elements show in Browser print preview but are not actually being printed.
#200-Private Book do not populate a URL in the ArcGIS Online URL item

@LindsayThomas Is this the pull request you wanted me to wait for before we do any certification testing?

@conklinbd yes. I am testing it, as I type this


libtiff: fetchpatch -> fetchurl (followup to #20206)

Motivation for this change
OCD
Things done

[ ] Tested using sandboxing
(nix.useSandbox on NixOS,
or option build-use-sandbox in nix.conf
on non-NixOS)
Built on platform(s)

[ ] NixOS
[ ] macOS
[ ] Linux

[ ] Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
[ ] Tested execution of all binary files (usually in ./result/bin/)
[ ] Fits CONTRIBUTING.md.

Pushed a fixed up version: 83f28fdd73.

I expect this "lower sensitivity" of the first character is because of nix just disregarding bits that overflow the hash length. (It's base32 and 256 = 51*5 + 1.) Maybe it would be nicer for nix to outlaw such extra bits, but I'm digressing...

Ugh. =/ I assume one is not supposed to randomly change the hash to
check that it will fetch cleanly (which was something what I did there),
but I have no idea how else I could do that.

Pushed a fixed up version: 83f28fdd73.

Let me fix nix: https://github.com/NixOS/nix/pull/1121

Yay!
Thanks for both!

It's a common thing to do, I believe. nix-prefetch-url -A is nice but it doesn't really work for lists.


my_path_id() overrides KolMafia library function

KolMafia was updated with a function to return the path id number for a path, which conflicts with the same function in Guide. Guide now won't load. Commenting out the function in Guide seems to fix the issue without any bad side effects, so probably a relatively easy refactor.

I did a Find and Replace changing my_path_id() to my_path_id_ez(). This also worked.


Update documentation with resource requirements

We should provide an initial strong caution in the docs about the resources that are needed for running the pipeline. Currently for alevin-fry we need at least 12 cpus & 24 GB of RAM (though 2X that if a run fails for any reason).
This means that running locally is possible but only on a fairly well-specced machine (not most laptops).
We should probably remove any references to running the workflow without setting up a profile, as that is just setting people up for failure.
As we address questions in #151, we might be able to rescope a bit (fewer cpus is possible, but probably not less RAM?), but the warning should remain.

Closed by #171