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

monitor: Introduce channel to buffer notifications and listeners #2933

Merged
merged 5 commits into from
Feb 27, 2018

Conversation

tgraf
Copy link
Member

@tgraf tgraf commented Feb 26, 2018

The current monitor code has two drawbacks:

  • sendEvent() blocks until the notification has been read, this can block fast path operations such as policy regeneration or even processing of L7 requests.
  • If multiple readers are connected, sending of events is blocked until all listeners have read the notification.

Changes:

  • Moves sendEvent() to NodeMonitor
  • Makes SendEvent() lockless and non-blocking. Notifications are enqueued
    to a channel and in case the channel is full, the notification is dropped.
  • Lost notifications are accounted for and reported
  • The writing to the pipe is made via a single Write() call to maximise the
    chances that either none of the message buffer or all of it is written to
    the pipe.
  • Decouple multiple monitor readers by introducing per listener queues

@tgraf tgraf added kind/bug This is a bug in the Cilium logic. wip area/monitor Impacts monitoring, access logging, flow logging, visibility of datapath traffic. release-note/minor This PR changes functionality that users may find relevant to operating Cilium. labels Feb 26, 2018
@tgraf tgraf requested a review from a team February 26, 2018 15:57
@tgraf tgraf requested a review from a team as a code owner February 26, 2018 15:57
No functional change of code

Signed-off-by: Thomas Graf <thomas@cilium.io>
@cilium cilium deleted a comment from houndci-bot Feb 26, 2018
@cilium cilium deleted a comment from houndci-bot Feb 26, 2018
@cilium cilium deleted a comment from houndci-bot Feb 26, 2018
@cilium cilium deleted a comment from houndci-bot Feb 26, 2018
@cilium cilium deleted a comment from houndci-bot Feb 26, 2018
@cilium cilium deleted a comment from houndci-bot Feb 26, 2018
@@ -96,3 +121,76 @@ func (nm *NodeMonitor) setState(state *models.MonitorStatus) {
nm.state = state
nm.Mutex.Unlock()
}

func (nm *NodeMonitor) SendEvent(typ int, event interface{}) error {

Choose a reason for hiding this comment

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

exported method NodeMonitor.SendEvent should have comment or be unexported

 * Makes SendEvent() lockless and non-blocking. Notifications are enqueued
   to a channel and in case the channel is full, the notification is dropped.
 * Lost notifications are accounted for and reported
 * The writing to the pipe is made via a single Write() call to maximise the
   chances that either none of the message buffer or all of it is written to
   the pipe.

Signed-off-by: Thomas Graf <thomas@cilium.io>
Signed-off-by: Thomas Graf <thomas@cilium.io>
This decouples multiple readers and avoids blocking other readers if one of the
readers can't keep it up.

Signed-off-by: Thomas Graf <thomas@cilium.io>
@tgraf
Copy link
Member Author

tgraf commented Feb 26, 2018

test-me-please

@tgraf tgraf added pending-review and removed wip labels Feb 26, 2018
return fmt.Errorf("Unable to encode metadata: %s", err)
}

msgBuf := append(metaBuf, payloadBuf...)
Copy link
Member

Choose a reason for hiding this comment

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

Can you add a comment into this code? I'm failing to understand why you are appending payloadBuf to metaBuf

Copy link
Member Author

Choose a reason for hiding this comment

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

The meta header comes before the payload. I'll move it into a func.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed


var (
mutex lock.Mutex
listeners = list.New()
listeners = make(map[*monitorListener]struct{})
Copy link
Member

Choose a reason for hiding this comment

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

Can't you use map[monitorListener]chan []byte instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

What's the advantage of that? It's not extendable.

Copy link
Member

Choose a reason for hiding this comment

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

I was trying to solve the problem of using a pointer as a key of a map. That can give problems when doing something like

func Foo(m monitorListener){
   _, exists := listeners[&m]
   // exists will always be false
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, because it's a different address.

Signed-off-by: Thomas Graf <thomas@cilium.io>
@tgraf tgraf requested a review from a team as a code owner February 27, 2018 00:02
@tgraf
Copy link
Member Author

tgraf commented Feb 27, 2018

test-me-please

}

select {
case nm.queue <- append([]byte{byte(typ)}, buf.Bytes()...):
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't typ already in the event object? In either case, doesn't this break the API we're presenting current clients?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, nevermind. This typ is different than the one you replaced.

@tgraf tgraf merged commit 8f1f166 into master Feb 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/monitor Impacts monitoring, access logging, flow logging, visibility of datapath traffic. kind/bug This is a bug in the Cilium logic. release-note/minor This PR changes functionality that users may find relevant to operating Cilium.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants