houseofcat / turbocookedrabbit

A user friendly RabbitMQ library written in Golang.
MIT License
107 stars 20 forks source link

CPU usage issue of the Rabbit Service #10

Closed jing-li-rocos closed 4 years ago

jing-li-rocos commented 4 years ago

The Rabbit Service start the auto publishing by default. The auto publishing also depends on the SleepOnIdle number to setup the loop. If the SleepOnIdle is very small, the CPU usage will be really high. Suggest to use channel to feed the auto publish rather than the for loop.

houseofcat commented 4 years ago

This was actually a performance enhancement, I am not sure I sold on it, but when <- wait to receive, it is more costly than default action of adding time.Sleep().

I am arguing over microseconds but it just became routine for me to put a default: sleep in all of my channel receive loops.

My suggestion is to set the SleepOnIdle to at least 1 ms, 0 means its disabled and it will loop as fast as Golang is capable of rapidly trying to look for messages to publish.

I may revisit this in the future just to simplify usage even more and take the small "hit" on performance.

houseofcat commented 4 years ago

With your other PR/Issue, I have added a quick func and a new ConnectionPool creation method.

NewConnectionPoolWithErrorHandler(config *PoolConfig, errorHandler func(error)) (*ConnectionPool, error)

Very straightforward to use, here is an example.

func TestCreateConnectionPoolWithErrorHandler(t *testing.T) {
    defer leaktest.Check(t)() // Fail on leaked goroutines.

    seasoning, err := tcr.ConvertJSONFileToConfig("badtest.json")
    if err != nil {
        return
    }

    cp, err := tcr.NewConnectionPoolWithErrorHandler(seasoning.PoolConfig, errorHandler)
    assert.Nil(t, cp)
    assert.Error(t, err)

    cp.Shutdown()
    TestCleanup(t)
}

func errorHandler(err error) {
    fmt.Println(err)
}
jing-li-rocos commented 4 years ago

Thanks so much, this is a great improvement.

jing-li-rocos commented 4 years ago

This was actually a performance enhancement, I am not sure I sold on it, but when <- wait to receive, it is more costly than default action of adding time.Sleep().

I am arguing over microseconds but it just became routine for me to put a default: sleep in all of my channel receive loops.

My suggestion is to set the SleepOnIdle to at least 1 ms, 0 means its disabled and it will loop as fast as Golang is capable of rapidly trying to look for messages to publish.

I may revisit this in the future just to simplify usage even more and take the small "hit" on performance.

Cool, thanks for your advise.

houseofcat commented 4 years ago

I am going to close out this issue for now, but I will think about ways of writing things a little easier to use out of the box - or have better documentation.

Any new issues please open them here as you run into them.