Live: comments for pipeline channel rule (#41639)

This commit is contained in:
Alexander Emelin 2021-11-15 15:02:27 +03:00 committed by GitHub
parent b88d21a6cb
commit d5ffff21ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 10 deletions

View File

@ -120,17 +120,46 @@ type SubscribeAuthChecker interface {
CanSubscribe(ctx context.Context, u *models.SignedInUser) (bool, error)
}
// LiveChannelRule is an in-memory representation of each specific rule, with Converter, FrameProcessor
// and FrameOutputter to be executed by Pipeline.
// LiveChannelRule is an in-memory representation of each specific rule to be executed by Pipeline.
type LiveChannelRule struct {
OrgId int64
Pattern string
PublishAuth PublishAuthChecker
SubscribeAuth SubscribeAuthChecker
Subscribers []Subscriber
DataOutputters []DataOutputter
Converter Converter
// OrgId this rule belongs to.
OrgId int64
// Pattern is a pattern for a channel which when matched results in the rule execution
// during Subscribe or Publish operations. This is very similar to HTTP router functionality but
// adapted for Grafana Live channels.
// We use a modified version of github.com/julienschmidt/httprouter for pattern matching logic
// (see tree package's README for more information).
Pattern string
// SubscribeAuth allows providing authorization logic for subscribing to a channel.
// If SubscribeAuth is not set then all authenticated users can subscribe to a channel.
SubscribeAuth SubscribeAuthChecker
// Subscribers allow modifying subscription properties and optionally call additional logic
// like opening a single stream to a plugin to consume channel events. If not set then
// subscription will have all options disabled, no initial data.
Subscribers []Subscriber
// PublishAuth allows providing authorization logic for publishing into a channel.
// If PublishAuth is not set then ROLE_ADMIN is required to publish.
PublishAuth PublishAuthChecker
// DataOutputters if set allows doing something useful with raw input data. If not set then
// we step further to the converter. Each DataOutputter can optionally return a slice
// of ChannelData to pass the control to a rule defined by ChannelData.Channel - i.e.
// DataOutputters for the returned ChannelData.Channel will be executed. Note that in
// this case input processing will skip PublishAuth of ChannelData.Channel. I.e. authorization
// rules defined by the first channel in a pipeline chain.
DataOutputters []DataOutputter
// Converter allows transforming raw input data to frames. The Converter can split raw data to
// slice of ChannelFrame. Each ChannelFrame is then processed according to ChannelFrame.Channel
// rules - i.e. FrameProcessors for the returned ChannelFrame.Channel will be executed.
// If ChannelFrame.Channel is empty then we proceed with the current rule towards
// applying its FrameProcessors.
Converter Converter
// FrameProcessors can have logic to modify data.Frame before applying FrameOutputters.
FrameProcessors []FrameProcessor
// FrameOutputters if set allow doing something useful with data.Frame. Each FrameOutputter
// can optionally return a slice of ChannelFrame to pass the control to a rule defined
// by ChannelFrame.Channel.
FrameOutputters []FrameOutputter
}

View File

@ -1,4 +1,4 @@
This is a tree code from https://github.com/julienschmidt/httprouter with an important fixes made inside Gin web framework.
This is a tree code from https://github.com/julienschmidt/httprouter with an important fixes/improvements made inside [Gin](https://github.com/gin-gonic/gin) web framework.
See:
* https://github.com/julienschmidt/httprouter/pull/329
@ -7,3 +7,25 @@ See:
See also https://github.com/julienschmidt/httprouter/issues/235 that's the reason why we can't use a custom branch patched with fixes.
Original LICENSE and copyright left unchanged here.
## How channel pattern matching works
As stated in [httprouter readme](https://github.com/julienschmidt/httprouter#features) about route matching behavior:
> Only explicit matches: With other routers, like http.ServeMux, a requested URL path could match multiple patterns. Therefore they have some awkward pattern priority rules, like longest match or first registered, first matched. By design of this router, a request can only match exactly one or no route. As a result, there are also no unintended matches
This copy of the httprouter follows this semantics. But it also contains several improvements where original httprouter was too restrictive.
One possible way is to start with `tree_test.go` file for routing examples.
What's possible:
* Possible to define explicit patterns without any parameters: `stream/metrics/cpu`, `stream/metrics/mem`, `stream/metrics/cpu/spikes`
* Possible to have named parameter to match multiple channels: `stream/metrics/:metric`, `stream/metrics/:metric/spikes`
* Possible to have `stream/metrics/:metric` and `stream/metrics/cpu` defined together so a version without named parameter is preferred when matching
* Possible to use catch-all parameters like `stream/metrics/*rest` which will match multiple segments
What's impossible:
* Having 2 patterns like this: `stream/:scope/cpu` and `stream/metrics/:metric` since it will cause conflict in the underlying tree
* Having pattern like `stream/metrics/:metric` while you already have `stream/*rest` again this is a conflict. So use catch-all parameters only in cases where you know for sure there won't be any sub-patterns in the future for which you need to override the behavior.