-
Notifications
You must be signed in to change notification settings - Fork 371
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
Allow concurrent, re-creatable usage #44
Conversation
Build failed. I used math/rand.Rand as an io.Reader and it failed saying it does not implement the io.Reader interface. It does not fail in my env, I think it is because of the Go version in the travis build is old. Although I see that math/rand.Rand implements io.Reader since 2015. Anyway, it is just for the tests, I will use a string reader instead. |
uuid_source_test.go
Outdated
|
||
func TestUuidSources(t *testing.T) { | ||
|
||
myString, _ := regen.Generate("[a-zA-Z]{1000}") |
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.
Rather than depend on another external package (creating another dependency) why not just make a very simple reader that returns a deterministic set based on some seed. For example:
type reader struct {
n int
c int
}
func (r *reader) Read(buf []byte) (int, error) {
// Make an uninitialized reader just return sequential bytes.
if r.n == 0 {
r.n = 1
}
c, n := r.c, r.n
for i := range buf {
c = (c + n) * n
buf[i] = byte(c)
}
r.c = c
return len(buf), nil
}
uuid_source.go
Outdated
// Calling NewSource with nil sets the random number generator to a default | ||
// generator. | ||
func NewSource(r io.Reader) UuidSource { | ||
var uuidSource UuidSource |
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.
return Source{render: r}
No reason to special case nil. They can pass in rand.Reader if they want.
uuid_source.go
Outdated
// | ||
// It is useful when a process need its own random number generator, | ||
// e.g. when running some processes concurrently. | ||
type UuidSource struct { |
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.
It would be UUIDSource, but if you are mimicking math/rand then just call it Source.
One issue with this setup it you still can only have a single rander function. Rather than add all of this complexity, it might be easier to simply create one new function, say NewRandomFromReader (I don't really like that name, it is a bit of a mouthful, but I don't expect it to be used often at all).
func NewRandomFromReadr(r io.Reader) (UUID, error)
Now an external package can create this type if they want.
type Source struct {
r io.Reader
}
func NewUUIDSource(r io.Reader) Source {
return Source{r: r}
}
func (s Source) NewRandom() (uuid.UUID, error) {
return uuid.NewRandomFromReader(s.r)
}
That will keep the uuid package cleaner.
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.
@pborman , Thanks for looking into this PR!
Let me ask to clarify - are you suggesting here that instead of everything in the uuid_source file, we just add the func NewRandomFromReadr(r io.Reader) (UUID, error)
function to version4.go
and let the user build the structs around it if they need? (it is actually the func newRandom(r io.Reader) (UUID, error)
that I added there). I am not clear, as you are also commenting on the content of the uuid_source files.
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.
Yes, that is exactly correct. And yes, the NewRandomFromReader is essentially the newRandom function you added. The uuid_source files would no longer be needed, although a simple test showing that NewRandomFromReader did in fact use the supplied reader would probably be a good addition. This could be very simple where you have a bytes.NewReader that has 16 bytes of data and the first NewRandomFromReader gives you the UUID you expect and the second NewRandomFromReader returns an error.
You might want to consider putting a package in GitHub that has the functionality of your uuid_source file so others can also use it if they need that sort of functionality.
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.
ok, Got it.
You might want to consider putting a package in GitHub that has the functionality of your uuid_source file so others can also use it if they need that sort of functionality.
A package for using it seems too much for just few lines of code. Maybe I'll just add an example?
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.
@pborman , do you still intend to merge this? Thank you! |
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.
LGTM
Sorry for the delay. Thank you for the contribution. |
Related to issue #43.
To enable concurrent and re-creatable usage, I have added a
UuidSource
, similar to the source inmath/rand
.It holds its own random number generator (the rander).
I have added only the methods that seemed relevant: SetRand(), NewRandom() (version 4) and New(). From what I saw, other methods do not use random number generator (except the clock sequence but this can't be recreated anyway).