Skip to content
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

Expose the librdkafka stats as events in the go client #57

Merged
merged 1 commit into from
May 11, 2017

Conversation

hqin
Copy link
Contributor

@hqin hqin commented Apr 15, 2017

@edenhill Please review the changes along with the librdkafka PR confluentinc/librdkafka#1171 ("added support for stats as events")

@hqin hqin requested a review from edenhill April 15, 2017 00:15
if mt.msgcnt == int64(cap(mt.msgs)) {
mt.t.Logf("***** Buffer full. not saving message: %v\n", e)
} else {
// mt.t.Logf("Saving message to mt.msgs[%d]: %v\n", mt.msgcnt, e)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove comment

} else {
// mt.t.Logf("Saving message to mt.msgs[%d]: %v\n", mt.msgcnt, e)
mt.msgs[mt.msgcnt] = e
mt.msgcnt++
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is msgcnt needed, isn't len(mt.msgs) sufficient?

}
case PartitionEOF:
break // silence
case *Stats:
mt.t.Logf("Stats: %v", e)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSON should be verified to be syntactically correct, if there is an easy way to do that with Go without requiring full-blow corresponding go types

mt.t.Fatalf("Consumer error: %v", e)
//mt.t.Logf("Ignored event: %v\n", e)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove comment

default:
// there are other unhandled events such as OffsetsCommitted
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this meant as a warning or fixme, ..?
Maybe we should handle it instead.

@@ -252,7 +285,9 @@ func producerTest(t *testing.T, testname string, testmsgs []*testmsgType, pc pro
}

mt := msgtrackerStart(t, len(testmsgs))

if pc.withStats {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't this be set along with statistics.interval.ms at line ~276?


// verify that stats events are received
if pc.withStats {
if mt.statscnt == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

combine into one if statement

@@ -351,7 +403,9 @@ func consumerTest(t *testing.T, testname string, msgcnt int, cc consumerCtrl, co

expCnt := msgcnt
mt := msgtrackerStart(t, expCnt)

if cc.withStats {
mt.withStats = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dito

if cc.withStats {
//wait for a while for stats to show up
for i := 0; i < 3; i++ {
if mt.statscnt != 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this thread-safe? mt.statscnt is updated through another go-routine, right?
I suggest changing this to a channel instead to signal completion.
E.g., let the stats receiving go-routine count the number of stats and send a "done" message on a channel when it is done, which is waited on here (with a reasonable timeout).

@@ -552,6 +622,18 @@ func TestProducerFuncDR(t *testing.T) {
})
}

// test producer function-based API with stats and delivery report
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with librdkafka I'd like to see a unittest for the stats that doesnt rely on broker connectivity.

@edenhill
Copy link
Contributor

This looks great! Just a couple of things needs sorting out

@edenhill
Copy link
Contributor

edenhill commented May 2, 2017

@hqin Can you rebase and squash/fixup your commits to a single one?
Since the follow-up commit is quite large it makes it easier to review the full thing atomically.

Something like:

 $ git checkout master
 $ git pull origin master
 $ git checkout <yourbranch>
 $ git rebase -i master
 # in the editor, mark your second commit with "fixup" (or "f") and move it just below your first commit (if not already there) to silently squash it into your previous commit
 $ git log   # verify that there is only one commit
 # Force push
 $ git push --dry-run --force origin <yourbranch>   # not master!
 # when you think that looks good, remove --dry-run


// test if the stats string can be decoded into JSON
var raw map[string]interface{}
json.Unmarshal([]byte(e.String()), &raw) // convert string to json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should check for err return here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Value: []byte("Own drChan"), Key: []byte("This is my key")}

}
p.Flush(2000)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since no brokers are configured and the default message.timeout.ms is 5 minutes this flush(2s) won't do anything.

I suggest removing it and just relying on the timeout below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed p.Flush()

func testProducerFunc(t *testing.T, withProducerChannel bool) {

p, err := NewProducer(&ConfigMap{
"statistics.interval.ms": 500,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason this is so "high"? 50 ms should suffice

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to 50ms

@edenhill
Copy link
Contributor

LGTM.

@edenhill edenhill merged commit 18b5a55 into confluentinc:master May 11, 2017
t.Fatalf("json unmarshall error: %s", err)
}
t.Logf("Stats['name']: %s", raw["name"])
close(statsReceived)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edenhill If the eventCh has more than one Stats messages, then statsReceived would be closed twice, which should panic the program. I wonder how this actually can work ? In my understanding, golang channel cannot be closed twice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants