FAQ
I got a simple password generator running inside an HTTP handler:

var buffer bytes.Buffer

func generatePassword(w http.ResponseWriter, r *http.Request) {
        buffer.Reset()

        index := rand.Intn(4)

        for i := 0; i <= 10; i++ {
               buffer.WriteString(buk[index][rand.Intn(len(buk[index]))])
        }

        log.Println(buffer.String())
}


When rushing with tons of requests on this handler, it sometimes doesn't
clear a buffer properly. Visually, the next password gets appended to the
previous one, like:

mXdh30ds1m
mXdh30ds1mKaSzXmcVkfDl

Yes I can just create a new buffer everytime in this handler, but what if I
really need to reuse it like that?

The problem can be seen when running on multiple cores. I've tried it with
GOMAXPROCS(1), and didn't get such an issue, well, *almost*, bcz there
actually was 1 or 2 times the buffer also didn't get cleared.

Go 1.6.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Dan Kortschak at Feb 22, 2016 at 11:09 am
    Run that under the race detector and you'll see you have a race.

    On 22/02/2016, at 9:34 PM, "vadimyer@gmail.com " wrote:

    I got a simple password generator running inside an HTTP handler:


    var buffer bytes.Buffer

    func generatePassword(w http.ResponseWriter, r *http.Request) {
            buffer.Reset()

            index := rand.Intn(4)

            for i := 0; i <= 10; i++ {
                   buffer.WriteString(buk[index][rand.Intn(len(buk[index]))])
            }

            log.Println(buffer.String())
    }

    When rushing with tons of requests on this handler, it sometimes doesn't clear a buffer properly. Visually, the next password gets appended to the previous one, like:

    mXdh30ds1m
    mXdh30ds1mKaSzXmcVkfDl

    Yes I can just create a new buffer everytime in this handler, but what if I really need to reuse it like that?

    The problem can be seen when running on multiple cores. I've tried it with GOMAXPROCS(1), and didn't get such an issue, well, *almost*, bcz there actually was 1 or 2 times the buffer also didn't get cleared.

    Go 1.6.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dave Cheney at Feb 22, 2016 at 11:09 am
    i recommend running your program with the race detector, the problem will be clear.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Davis at Feb 22, 2016 at 12:09 pm

    On Mon, Feb 22, 2016, at 11:04 AM, vadimyer@gmail.com wrote:
    I got a simple password generator running inside an HTTP handler:


    *var*buffer bytes.Buffer

    *func *generatePassword(w http.ResponseWriter, r *http.Request){
    buffer.Reset()

    index := rand.Intn(4)

    *for*i :=; i <=10; i++{              buffer.WriteString(buk[index][ra-
    nd.Intn(len(buk[index]))]) }

    log.Println(buffer.String()) }


    When rushing with tons of requests on this handler, it sometimes
    doesn't clear a buffer properly. Visually, the next password gets
    appended to the previous one, like:


    mXdh30ds1m mXdh30ds1mKaSzXmcVkfDl


    Yes I can just create a new buffer everytime in this handler, but what
    if I really need to reuse it like that?

    The problem can be seen when running on multiple cores. I've tried it
    with GOMAXPROCS(1), and didn't get such an issue, well, *almost*, bcz
    there actually was 1 or 2 times the buffer also didn't get cleared.

    Go 1.6.
    Think about what happens when you have two incoming requests to call
    generatePassword. Each request will be on a separate goroutine. The
    first goroutine calls buffer.Reset and then starts the loop. However the
    goroutine can be pre-empted at any function call so imagine half way
    through the loop it gets suspended and the second goroutine stats
    running the function. It resets the buffer. Then it gets pre-empted and
    the first goroutine continues. Your buffer is now corrupted.

    You can't share the buffer like this unless you use a mutex to prevent
    multiple goroutines from accessing the buffer at the same time. Or, as
    you suggested, use a separate buffer per goroutine.

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Vadimyer at Feb 22, 2016 at 12:42 pm
    Yes, thanks for that. First time I've ran a race detector, didn't know what
    it is :)
    AFAIK, blocking with mutex will greatly degrade the overall performance,
    especially when the goroutine gets stuck in some condition (?)
    If yes, in this case it's really better to just use an immutable buffer.


    понедельник, 22 февраля 2016 г., 14:04:34 UTC+3 пользователь
    vadi...@gmail.com написал:
    I got a simple password generator running inside an HTTP handler:

    var buffer bytes.Buffer

    func generatePassword(w http.ResponseWriter, r *http.Request) {
    buffer.Reset()

    index := rand.Intn(4)

    for i := 0; i <= 10; i++ {
    buffer.WriteString(buk[index][rand.Intn(len(buk[index]))])
    }

    log.Println(buffer.String())
    }


    When rushing with tons of requests on this handler, it sometimes doesn't
    clear a buffer properly. Visually, the next password gets appended to the
    previous one, like:

    mXdh30ds1m
    mXdh30ds1mKaSzXmcVkfDl

    Yes I can just create a new buffer everytime in this handler, but what if
    I really need to reuse it like that?

    The problem can be seen when running on multiple cores. I've tried it with
    GOMAXPROCS(1), and didn't get such an issue, well, *almost*, bcz there
    actually was 1 or 2 times the buffer also didn't get cleared.

    Go 1.6.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Vadimyer at Feb 22, 2016 at 12:46 pm
    Probably I can detect if a routine is locked and allocate a new buffer if
    necessary then?

    понедельник, 22 февраля 2016 г., 14:04:34 UTC+3 пользователь
    vadi...@gmail.com написал:
    I got a simple password generator running inside an HTTP handler:

    var buffer bytes.Buffer

    func generatePassword(w http.ResponseWriter, r *http.Request) {
    buffer.Reset()

    index := rand.Intn(4)

    for i := 0; i <= 10; i++ {
    buffer.WriteString(buk[index][rand.Intn(len(buk[index]))])
    }

    log.Println(buffer.String())
    }


    When rushing with tons of requests on this handler, it sometimes doesn't
    clear a buffer properly. Visually, the next password gets appended to the
    previous one, like:

    mXdh30ds1m
    mXdh30ds1mKaSzXmcVkfDl

    Yes I can just create a new buffer everytime in this handler, but what if
    I really need to reuse it like that?

    The problem can be seen when running on multiple cores. I've tried it with
    GOMAXPROCS(1), and didn't get such an issue, well, *almost*, bcz there
    actually was 1 or 2 times the buffer also didn't get cleared.

    Go 1.6.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Bruno Albuquerque at Feb 22, 2016 at 1:13 pm
    You are over-engineering. Just allocate a new buffer per request. If it
    ever proves to be a bottleneck (which is very unlikely) then you try
    something else.

    Em seg, 22 de fev de 2016 às 09:46, <vadimyer@gmail.com> escreveu:

    Probably I can detect if a routine is locked and allocate a new buffer if
    necessary then?


    понедельник, 22 февраля 2016 г., 14:04:34 UTC+3 пользователь
    vadi...@gmail.com написал:
    I got a simple password generator running inside an HTTP handler:
    var buffer bytes.Buffer

    func generatePassword(w http.ResponseWriter, r *http.Request) {
    buffer.Reset()

    index := rand.Intn(4)

    for i := 0; i <= 10; i++ {
    buffer.WriteString(buk[index][rand.Intn(len(buk[index]))])
    }

    log.Println(buffer.String())
    }


    When rushing with tons of requests on this handler, it sometimes doesn't
    clear a buffer properly. Visually, the next password gets appended to the
    previous one, like:

    mXdh30ds1m
    mXdh30ds1mKaSzXmcVkfDl

    Yes I can just create a new buffer everytime in this handler, but what if
    I really need to reuse it like that?

    The problem can be seen when running on multiple cores. I've tried it
    with GOMAXPROCS(1), and didn't get such an issue, well, *almost*, bcz there
    actually was 1 or 2 times the buffer also didn't get cleared.

    Go 1.6.
    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Stanislav Paskalev at Feb 22, 2016 at 3:07 pm
    See sync.Pool from the standard library if a new buffer per request doesn't
    work for you.
    On Monday, February 22, 2016 at 2:46:48 PM UTC+2, vadi...@gmail.com wrote:

    Probably I can detect if a routine is locked and allocate a new buffer if
    necessary then?

    понедельник, 22 февраля 2016 г., 14:04:34 UTC+3 пользователь
    vadi...@gmail.com написал:
    I got a simple password generator running inside an HTTP handler:

    var buffer bytes.Buffer

    func generatePassword(w http.ResponseWriter, r *http.Request) {
    buffer.Reset()

    index := rand.Intn(4)

    for i := 0; i <= 10; i++ {
    buffer.WriteString(buk[index][rand.Intn(len(buk[index]))])
    }

    log.Println(buffer.String())
    }


    When rushing with tons of requests on this handler, it sometimes doesn't
    clear a buffer properly. Visually, the next password gets appended to the
    previous one, like:

    mXdh30ds1m
    mXdh30ds1mKaSzXmcVkfDl

    Yes I can just create a new buffer everytime in this handler, but what if
    I really need to reuse it like that?

    The problem can be seen when running on multiple cores. I've tried it
    with GOMAXPROCS(1), and didn't get such an issue, well, *almost*, bcz there
    actually was 1 or 2 times the buffer also didn't get cleared.

    Go 1.6.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Mikespook at Feb 22, 2016 at 10:19 pm
    If you really consider using ONE buffer in your application (the solution
    may not be efficient as you expected, but can help you avoiding the race
    condition), you can use Producer-Consumer pattern.

    Using a standalone goroutine to produce passwords and put them into a
    channel, while handlers read passwords from the channel.

    Just like this:
    https://github.com/mikespook/golib/blob/master/autoinc/autoinc.go#L21
    On 23 February 2016 at 04:07, Stanislav Paskalev wrote:

    See sync.Pool from the standard library if a new buffer per request
    doesn't work for you.

    On Monday, February 22, 2016 at 2:46:48 PM UTC+2, vadi...@gmail.com wrote:

    Probably I can detect if a routine is locked and allocate a new buffer if
    necessary then?

    понедельник, 22 февраля 2016 г., 14:04:34 UTC+3 пользователь
    vadi...@gmail.com написал:
    I got a simple password generator running inside an HTTP handler:

    var buffer bytes.Buffer

    func generatePassword(w http.ResponseWriter, r *http.Request) {
    buffer.Reset()

    index := rand.Intn(4)

    for i := 0; i <= 10; i++ {
    buffer.WriteString(buk[index][rand.Intn(len(buk[index]))])
    }

    log.Println(buffer.String())
    }


    When rushing with tons of requests on this handler, it sometimes doesn't
    clear a buffer properly. Visually, the next password gets appended to the
    previous one, like:

    mXdh30ds1m
    mXdh30ds1mKaSzXmcVkfDl

    Yes I can just create a new buffer everytime in this handler, but what
    if I really need to reuse it like that?

    The problem can be seen when running on multiple cores. I've tried it
    with GOMAXPROCS(1), and didn't get such an issue, well, *almost*, bcz there
    actually was 1 or 2 times the buffer also didn't get cleared.

    Go 1.6.
    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.


    --
    Xing Xing (邢星)
    mikespook <mikespook@gmail.com>
    http://mikespook.com

    <http://tr.grammarly.com/aff_c?offer_id=97&aff_id=7225&file_id=1242>

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedFeb 22, '16 at 11:04a
activeFeb 22, '16 at 10:19p
posts9
users7
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase