-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: use portable C++ RNG #11627
base: master
Are you sure you want to change the base?
fix: use portable C++ RNG #11627
Conversation
@bryanhonof can you try the thing I suggested in the issue of making Also, can you remove the |
Sure, although I didn't quite understand why it'd need to be part of that t.b.h. I liked the way you could use this implementation as a functor, and have the constructor define the range, giving people working on the Nix codebase a nice way to generate random numbers in the future, without doing the whole init dance. We'll lose that behavior if I'm going to instantiate it in
I believe I already did, |
dfd1ce7
to
563a6dd
Compare
Added a generic Random as a public member. lmkwyt. |
8400a1f
to
5d60ccc
Compare
src/libstore/sqlite.cc
Outdated
@@ -258,7 +259,7 @@ void handleSQLiteBusy(const SQLiteBusy & e, time_t & nextWarning) | |||
is likely to fail again. */ | |||
checkInterrupt(); | |||
/* <= 0.1s */ | |||
std::this_thread::sleep_for(std::chrono::milliseconds { rand() % 100 }); | |||
std::this_thread::sleep_for(std::chrono::milliseconds { Random{0, 100}() }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you make SQLite
require a reference to a Random
and then for the LocalStore
use the one you just added, and then add one on NarInfoDiskCacheImpl
(the other user of SQLite
)?
Make sure to add some doxygen to the Random & rng
saying what it is used for :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function calling that Random
, handleSQLiteBusy()
, isn't a member of the SQLite
struct. Would it be okay to just keep the functor call here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'll need a bit of help on how to resolve this one. I'm not quite sure where to initialize the RandomNumberGenerator
when it comes to this specific function. Maybe we could create a thread_local
global rng for use-cases like this, but is that a suitable solution?
Should I also replace the code in nix/src/libstore/filetransfer.cc Lines 45 to 46 in 96ba7f9
|
I think it is good if the call-site specifies the distribution, the state is just to avoid consulting the somewhat icky device random global variable. Feel free to change |
@bryanhonof Sure feel free to change I guess |
I don't think that using
The question is: Which properties shall this RNG have? For testing a PRNG is useful, i.e. the same seed shall generate the same sequence of numbers. If the generator is non-deterministic, then this is not possible. |
I did see that comment, I honestly wouldn't know what else to use. Do you maybe think having a second constructor that accepts a
I'm honestly not sure, might be that @Ericson2314 knows?
As far as I can see, no. I don't expect to support generating random characters any time soon. Maybe floats or doubles.
I've used |
If it uses |
5d60ccc
to
6677a68
Compare
42acd1c
to
0b0d5d8
Compare
9dc7cd5
to
94cb5a7
Compare
|
||
// Inspired by the book "A Tour of C++, Third Edition" (ISBN-10 0136816487) | ||
template<typename T, typename Distribution, typename Engine> | ||
struct RandomNumberGenerator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a pseudo random generator, right? We should probably put this in the name so people not use it in the wrong place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is any random number generator really a true random number generator? 😁
No, in all seriousness, I'm not sure. If people would want to use this for cryptographic reasons, I don't think this header is the right choice. Linking against openssl, and using its facilities, would be way better. But PseudoRandomNumberGenerator
starts becoming very verbose as well. Maybe mention it in the comments of this header that it isn't meant for cryptographic reasons? Perhaps use Doxygen docs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe mentioning in the header that this should not be used for cryptographic purpose would be a good start.
tmpPath (the replacement), so we have to move it out of the | ||
way first. We'd better not be interrupted here, because if | ||
we're repairing (say) Glibc, we end up with a broken system. */ | ||
Path oldPath = fmt("%1%.old-%2%-%3%", storePath, getpid(), getLocalStore().rng()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't be part of this PR, but on linux, we can use renameat2 with RENAME_EXCHANGE to make the whole thing atomic without using a temporary directory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you make a seperate issue for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
94cb5a7
to
71ab474
Compare
I'm going to push a commit with the things I want. |
@bryanhonof I am afraid I am a bit back to the drawing board now that I don't see any PRNG "splitting" of the sort mentioned in https://www.tweag.io/blog/2020-06-29-prng-test/ in the C++ standard library. |
There's a related Lix commit that may fix #7273 that you may wish to backport instead |
I used "A Tour of C++, Third Edition" (ISBN-10 0136816487) as inspiration for the Random class. This replaces all occurrences of `rand()` and `srand()`. Co-authored-by: John Ericson <[email protected]> Co-authored-by: Eelco Dolstra <[email protected]>
71ab474
to
fc4cc5a
Compare
Motivation
Fixes #10541
Context
I took inspiration from "A Tour of C++, Third Edition" (ISBN-10 0136816487) to implement the
Random
class. Making it a bit easier for users to generate random numbers using C++'s portable RNG. The use ofstd::random_device
might be a bit overkill, and unnecessary, but I was having fun. 😅I'm also aware that this constantly creates instances of
Random
, and then instantly throws them away again. I thought about making this a singleton in some way, but then again, maybe the compiler is smart enough about this.There are other distribution mechanisms that we could use, I just went with
std::uniform_int_distribution
, since that's what the book uses.Priorities and Process
Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.