-
Notifications
You must be signed in to change notification settings - Fork 490
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
Add ability to load tasks/handlers from dir #1481
Conversation
27c8b04
to
1940364
Compare
client/v1/client.go
Outdated
@@ -203,8 +204,10 @@ type ExecutionStats struct { | |||
type TaskType int | |||
|
|||
const ( | |||
StreamTask TaskType = 1 | |||
BatchTask TaskType = 2 | |||
UndefinedTask TaskType = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which of these do we need?
client/v1/client.go
Outdated
@@ -213,6 +216,10 @@ func (tt TaskType) MarshalText() ([]byte, error) { | |||
return []byte("stream"), nil | |||
case BatchTask: | |||
return []byte("batch"), nil | |||
case UndefinedTask: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same.
client/v1/client.go
Outdated
@@ -2282,3 +2294,107 @@ func (d *Duration) UnmarshalText(data []byte) error { | |||
*d = Duration(dur) | |||
return nil | |||
} | |||
|
|||
// TODO: this is also used in kapacitor/main.go | |||
type dbrps []DBRP |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Export this and use in other package
services/load/config.go
Outdated
return nil | ||
} | ||
|
||
func (c Config) TasksDir() string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably doesn't need to be exported
services/load/config.go
Outdated
return filepath.Join(c.Dir, taskDir) | ||
} | ||
|
||
func (c Config) TemplatesDir() string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
services/load/service.go
Outdated
|
||
// HandlerFiles gets a slice of all files with the .json, .yml, and | ||
// .yaml file extentions in the configured handler directory. | ||
func (s *Service) HandlerFiles() ([]string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unexport
return handlers, nil | ||
} | ||
|
||
func (s *Service) Load() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add logging
services/load/service.go
Outdated
return nil | ||
} | ||
|
||
func (s *Service) loadTickscripts() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change to load tasks
services/load/service.go
Outdated
return nil | ||
} | ||
|
||
func (s *Service) loadTickscript(f string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
} | ||
|
||
func (s *Service) loadTemplate(f string) error { | ||
file, err := os.Open(f) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defer file.Close()
@nathanielc This should be in a reviewable state. I still need to add a few more tests to the server package so that I can be completely confident in the changes, but it should reviewable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking great. I made a bunch of comments below, mostly addressing your TODO questions.
client/v1/client.go
Outdated
@@ -2282,3 +2289,107 @@ func (d *Duration) UnmarshalText(data []byte) error { | |||
*d = Duration(dur) | |||
return nil | |||
} | |||
|
|||
// TODO: this is also used in kapacitor/main.go |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this TODO mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Old comment. Previously this code was in kapacitor/main.go
and unexported. I moved it here and exported it. The TODO
item was meant to remind me to update kapacitor/main.go
to use this code instead.
cmd/kapacitor/main.go
Outdated
if *dfile != "" { | ||
f, err := os.Open(*dfile) | ||
if err != nil { | ||
return errors.Wrapf(err, "faild to open file %s", *dfile) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo faild -> failed
cmd/kapacitor/main.go
Outdated
@@ -542,72 +541,15 @@ var ( | |||
dtype = defineFlags.String("type", "", "The task type (stream|batch)") | |||
dtemplate = defineFlags.String("template", "", "Optional template ID") | |||
dvars = defineFlags.String("vars", "", "Optional path to a JSON vars file") | |||
dfile = defineFlags.String("file", "", "Optional path to a YAML or JSON vars file") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the difference between -vars
and -file
?
Its not clear from the help text.
cmd/kapacitor/main.go
Outdated
ID: id, | ||
TemplateID: *dtemplate, | ||
Type: ttype, | ||
DBRPs: ddbrp, | ||
TICKscript: script, | ||
Vars: vars, | ||
Status: client.Disabled, | ||
}) | ||
} | ||
if *dfile != "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't the logic if else
here? Same question below for the update options logic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I totally follow. Are you saying to do
if *dfile != "" {
o, err := fileVars.CreateTaskOptions()
if err != nil {
return err
}
_, err = cli.CreateTask(o)
} else {
o := client.CreateTaskOptions{
ID: id,
TemplateID: *dtemplate,
Type: ttype,
DBRPs: ddbrp,
TICKscript: script,
Vars: vars,
Status: client.Disabled,
}
_, err = cli.CreateTask(o)
}
this instead?
@@ -822,7 +804,7 @@ func doDefineTemplate(args []string) error { | |||
} | |||
|
|||
func defineTopicHandlerUsage() { | |||
var u = `Usage: kapacitor define-topic-handler <topic id> <handler id> <path to handler spec file> | |||
var u = `Usage: kapacitor define-topic-handler <path to handler spec file> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay! Now everything is in the handler file.
show-topic-handler
and list topic-handlers
handlers haven't changed. So they still require passing both the topic ID and handler ID as args correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup.
services/load/config.go
Outdated
return fmt.Errorf("directory %s must be contain subdirectory %s", c.Dir, handlerDir) | ||
} | ||
|
||
// TODO: we should probably check that we have the correct permissions to access the necessary files |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to explicitly check permissions unless we want the files to be only user/group accessible for security purposes. Which is not the case here. So if we can read them great, if not we will report the error.
services/load/service.go
Outdated
"github.com/pkg/errors" | ||
) | ||
|
||
var defaultURL = "http://localhost:9092" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK here is a crazy idea.
We need to go through the API in order to get all the validation logic etc that is all there. But we do not need to actually make a network connection. Assuming that a localhost network connection will work is not valid in many environments, docker being a common one.
What if we simply created the HTTP request and then called ServerHTTP directly on the API server. This would be in effect the exact same thing but we never make and a network connection.
This may mean exposing the Client.Do method or something so that you can reuse the client.
I am thinking something like this
kapacitor/integrations/benchmark_test.go
Line 224 in d19fc26
httpdService.Handler.ServeHTTP(responseRecorder, writeRequest) |
Doing it this way will eliminate a whole class of network bugs where we cannot reliably determine the connection credentials to ourselves. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I really like that.
|
||
handlersDir := s.config.handlersDir() | ||
|
||
files, err := ioutil.ReadDir(handlersDir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this error is an error about the directory not existing silently ignore it. Meaning if the handlers
dir does not exists, that is not an error but rather an indication that there are zero handlers to define.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in load/config.go
the Validate
method requires that the directory specified must have subdirectories tasks
, templates
, and handlers
. Should I relax this requirement?
tick/ast/node.go
Outdated
} | ||
|
||
// TODO: Not sure how I feel about client.TaskType importing from client | ||
func (n *ProgramNode) DBRPs() []client.DBRP { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general importing the client types in the server code makes sense as it ensures that the server and client are using the same types. But here we are not server code but rather an independent package that handles parsing scripts.
I recommend that you use the AST nodes as the public API from the tick
package and move these methods into the server code where needed. So it would look something like dbrpsFromProgram(*ast.ProgramNode) []client.DBRP
. Does that help?
tick/ast/node.go
Outdated
@@ -981,6 +1024,101 @@ func newProgram(p position) *ProgramNode { | |||
} | |||
} | |||
|
|||
func NewProgramNodeFromTickscript(tickscript string) (*ProgramNode, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like this function name, but I get that it is a common need to be able to type assert the ast.Node to its concrete type. Should we just have the Parse
method return the concrete type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW The reasons I don't like the name is without reading the function's source I thought it was doing some kind of special operation to return a ProgramNode from a TICKscript instead of just using the Parse method.
Another option would be to move this method to the package where it is consumed as a helper method.
cmd/kapacitord/main.go
Outdated
}() | ||
break Loop | ||
|
||
case s := <-signalCh: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nathanielc there has to be a better way than this, but I couldn't find an example. This could be my end-of-day brain not thinking straight. Thoughts?
influxdata/chronograf#1721 will be able to remove the |
@121watts ^^ |
Seems to be having an issue with batch tasks. Not exactly sure why. Will investigate. |
Hi, I'm looking for a convergence method for alerts. |
@F4ncyMooN This PR is a little bit different. This PR introduces a way to load tasks and templates from a directory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this looks good. I just had a few code organization questions below.
cmd/kapacitor/main.go
Outdated
|
||
// Parse string of the form "db"."rp" where the quotes are optional but can include escaped quotes | ||
// within the strings. | ||
func (d *dbrps) Set(value string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why was this moved to the client package? The Set
method is part of the flag.Value
interface, which seems like it belongs here in the main package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
client.TaskVars
ended up needing the same DBRP logic so rather than having two copies of the type, one in the main
package and one in the client
package I figured that I'd move it into client. I'm happy to have two separate types if you think thats best.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did the client.TaskVars
need to implement the flag.Value
interface?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the type in the client package should implement a TextUnmarshaler interface and then the type in the main package uses the type from the client package and adds the Set method to its own type? Does that work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nathanielc Looks like implementing TextUnmarshaler
causes issues with the regular JSON marshaling. Does having a method Unmarshal
on the client.DBRP
type work?
cmd/kapacitord/main.go
Outdated
}() | ||
Loop: | ||
for { | ||
select { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This select statement has only a single case, which means this can be simplified to for s := range signalCh {...}
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, ok so further down we check for a second signal. Maybe we should just keep a state about the signals we have received so its clear how transitions occur.
cmd/kapacitord/main.go
Outdated
} | ||
} | ||
|
||
// This should never happen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about os.Interrupt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nathanielc what should happen on os.Interrupt
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removing comment.
cmd/kapacitord/main.go
Outdated
m.Logger.Println("I! SIGHUP received, Reloading tasks/templates/handlers directory...") | ||
if err := cmd.Server.LoadService.Load(); err != nil { | ||
m.Logger.Println(fmt.Sprintf("E! Failed to reload tasks/templates/handlers: %s", err)) | ||
if _, ok := err.(load.HardError); ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What other kinds of errors are returned? Should we push this logic into the server type? Maybe something in this method https://github.com/influxdata/kapacitor/blob/master/server/server.go#L882. Plus a method on the Server type to reload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not totally sure I follow. I think this logic might belong here. Load
can return few different error types, but there's a configuration setting that specifies what should happen to the runtime in the case of an error. If the configuration says crash on error we wrap any errors coming from Load
the error with a load.HardError
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
cmd/kapacitord/run/command.go
Outdated
@@ -127,6 +127,11 @@ func (cmd *Command) Run(args ...string) error { | |||
if err := s.Open(); err != nil { | |||
return fmt.Errorf("open server: %s", err) | |||
} | |||
|
|||
if err := s.LoadService.Load(); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't this part of the Open process for the Server?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
@nathanielc addressed most of the issues, only thing I was a bit unsure of was #1481 (comment) |
cmd/kapacitord/main.go
Outdated
|
||
case syscall.SIGHUP.String(): | ||
m.Diag.Info("SIGHUP received, reloading tasks/templates/handlers directory...") | ||
if err := cmd.Server.LoadService.Load(); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking, instead of doing cmd.Server.LoadService.Load() and handing the error types here in the main package, create a method on the server called Reload or something, that if it returns an error at all causes the Server to crash.
Then inside that method determine if the underlying errors returned from LoadService.Load are worth crashing. That way the main function crashes if it gets any error, and the Server contains the logic on what errors cause crashes.
Does that help?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup.
@nathanielc I think I addressed all the previous issues. |
I am testing this out locally, here are some of the issues I ran into:
Those are the issues I ran into, mostly usability issues and the fact the the README in the examples dir is out of date so it lead me astray. Its super nice to be able to define the tasks from dirs like this! Thanks! |
I am testing this out locally, here are some of the issues I ran into:
Fixed
fixed.
fixed |
This was intentional. Hard errors only apply when re-loading when the process is running. The idea here was that if you’re starting launching from a directory that the tasks/templates/handlers should be treated as configuration and therefore the server should not start until they are valid. However if you’re running already and you make a change to your tasks/templates/handlers an error with one of those should not crash your server. Happy to change this though.
How do we do this? My current thought would be to have some kind of
Which examples were/are problematic? When I use that directory as my load directory everything seems to work fine.
Should this be done by validating the file before even passing it to the API? |
Hmm, I am beginning to think we should just remove the
My though was track a list of tasks/templates/handlers that are created from the load service and then when the load service runs, if the file system no longer defines that task/template/handler then delete it. This list should be stored in the kapacitor.db file. It could be an explicit list or simply a new property on the data being stored for each item. Does that make sense?
I'll comment in-line on the issues I had.
No, I'd rather all validation logic live in the API, that way if someone isn't using the client they still get proper validation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comments on the README that were confusing.
examples/load/README.md
Outdated
|
||
`dir` specifies the directory where the definition files exist. | ||
|
||
The specified directory should have three subdirectories `tasks`, `templates`, and `handlers`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line implies that the directories must exist, which is not the case.
examples/load/README.md
Outdated
The `tasks` directory will contain will contain task tickscripts. | ||
|
||
The `templates` directory will contain both template tickscripts and the associated templated task | ||
definition files (either yaml or json). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These lines need to be updated to reflect the new behavior.
examples/load/README.md
Outdated
* `id` - the file name without the tick extension | ||
* `type` - determined by introspection of the task (stream, batch) | ||
* `kind` - task, template. defined using a `set statement` | ||
* `subscriptions` - defined using the `subscribe` keyword followed by a specified subscription |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the syntax dbrp
now?
examples/load/README.md
Outdated
"window": {"type" : "duration", "value" : "1m" }, | ||
"slack_channel": {"type" : "string", "value" : "#alerts_testing" } | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is technically correct yaml but quite non-standard a confusing, this reads more like yaml
dbrp:
- telegraf.autogen
- telegraf.not_autogen
template: base_template
vars:
measurement:
type: string
value: cpu
where_filter:
type: lambda
value: "\"cpu\" == 'cpu-total'"
groups:
type: list
value:
- type: string
value: host
- type: string
value: dc
field:
type: string
value : usage_idle
warn:
type: lambda
value: "\"mean\" < 30.0"
crit:
type: lambda
value: "\"mean\" < 10.0"
window:
type: duration
value : 1m
slack_channel:
type: string
value: "#alerts_testing"
examples/load/README.md
Outdated
channel: '#alerts' | ||
``` | ||
|
||
the name of the file will be used as the handler id. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is false, the id is read from the file and the filename is not used.
@nathanielc removed the hard error condition and added the logic for deleting stale tasks/templates/handlers that were loaded from a directory. The todo items I have left are
|
@nathanielc added tests. Should be ready for final review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some comments.
examples/load/README.md
Outdated
|
||
`dir` specifies the directory where the definition files exist. | ||
|
||
The specified directory will check to see if any of three subdirectories `tasks`, `templates`, and `handlers` exists. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The configured dir
may contain any of these sub-directories: tasks
, templates
, and handlers
.
examples/load/README.md
Outdated
The `tasks` directory will contain will contain task tickscripts and and the associated templated task | ||
definition files (either yaml or json). | ||
|
||
The `templates` directory will contain both template tickscripts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The templates
directory will contain template tickscripts
examples/load/README.md
Outdated
|
||
The `templates` directory will contain both template tickscripts | ||
|
||
The `handlers` directory will contain will contain all topic handler definitions in yaml or json. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The handlers
directory will contain will contain topic handler definitions in yaml or json.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
examples/load/README.md
Outdated
``` | ||
dbrp "telegraf"."autogen" | ||
|
||
var measurement string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example is actually a template so it can't be placed in the tasks dir.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
examples/load/README.md
Outdated
dbrp: | ||
- telegraf.autogen | ||
- telegraf.not_autogen | ||
template: base_template |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be templated-id
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
examples/load/README.md
Outdated
|
||
### Templated Tasks | ||
|
||
Template variables may be added as either json or yaml. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the README should have a simple TICKscript above to demonstrate creating tasks.
Then in this Template section it should first define a TICKscript template. Then show how that template can be referenced from a file in the tasks
directory.
We want to make it clear that anything in the tasks
dir will create a task, and anything in the templates
dir will create a template.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a section on defining a template before and the templated tasks now use that template. Think that should be sufficient? Or did you have something else in mind?
server/server.go
Outdated
@@ -896,7 +896,7 @@ func (s *Server) Open() error { | |||
} | |||
|
|||
if err := s.LoadService.Load(); err != nil { | |||
return fmt.Errorf("loading tasks/templates/handlers: %s", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think its fine for the server to refuse to start if it has bad configuration, but we do not want it to crash from a simple typo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure exactly what to do with this. Should I keep the error here and do some checking of the type of error, or just leave it as is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What types of errors would you check for? Seems like if it errors at all it should return the error.
server/server.go
Outdated
@@ -1060,7 +1060,7 @@ func (s *Server) writeID(file string, id uuid.UUID) error { | |||
func (s *Server) Reload() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this function can't error anymore we should remove the error
return value and simplify the caller to not need to handle the error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Testing locally it works well.
Can you update the bash completion for the CLI changes?
services/load/service.go
Outdated
} | ||
|
||
func (s *Service) loadedTasks() ([]string, error) { | ||
items, err := s.items.List("tasks") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should create constants for the tasks
, templates
and handlers
strings, since they are part of the key for the DOA. A typo would corrupt the data :(.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
services/load/service.go
Outdated
|
||
func NewService(c Config, h http.Handler, d Diagnostic) (*Service, error) { | ||
cfg := client.Config{ | ||
URL: defaultURL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a unique user agent here so its clear the consumer of the API is this internal client from Load?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@nathanielc I think I got the completion right, but I'm not totally sure. I sometimes have issues with it on OSX. Does this seem right? |
Add check for tickscript defined dbrps Fix error that allowed you to set dbrps twice Add template and task dbrp via tickscript Remove dao test file Fix issue with updating task without dbrp values Add new template vars structure Load tasks and templates from directory Update define-topic-handler subcommand to 1 arg Add loadHandlers method to load service Add tests and prevent certain updates to templates Update parser to define dbrp as reference.referenc Fix issue where tasks weren't reloaded Replace correct topic handler Listen for SIGHUP to reload tasks/templates/handld Move dbrps type to client package Unexport internal functions Address todo items Make assorted changes suggested in PR Add test for dbrp Add tests for node task type and dbrps Fix comment Use ServeHTTP instead of making actual http req Add soft/hard configuration option Fix typos and remove TODO comments Don't error if the directories are missing Append load service Move util methods into task_store package Improve error messaging Clean up kapacitor and kapacitord mains Remove old TODO comment Add error check in doDefine Add load example directory Address issues from PR Add diagnostic to load service Add batch examples and tests Add reload method to server Add dbrp type to kapacitor main package Use explicit specification for dbrp in files Set sane default for demo config Skip load if directory doesn't exist Unwrap error so that correct error type Move templated tasks to task dir from templates Remove commented out code Remove hard error Add error stat to load service Delete tasks/templates/hanlders when appropriate Delete tasks/template/handlers when appropraite Cleanup example of load directory Add Error to load diagnostic Check for nil storage service Clean-up load functions Add test for load service Add test for topic-handlers Prevent server crash on error Fix wording in README Remove error from Reload function Make additional changes to README Crash on initial Load Add more to readme Add UserAgent and task string constants Update define-topic-handler completion
@nathanielc just rebased. I think things should be good to go now. |
Todo
Done
Todo
Required for all non-trivial PRs