| 520 | } |
| 521 | |
| 522 | func (c *Config) validate() error { |
| 523 | if c.CancelledJobRetentionPeriod < -1 { |
| 524 | return errors.New("CancelledJobRetentionPeriod time cannot be less than zero, except for -1 (infinite)") |
| 525 | } |
| 526 | if c.CompletedJobRetentionPeriod < -1 { |
| 527 | return errors.New("CompletedJobRetentionPeriod cannot be less than zero, except for -1 (infinite)") |
| 528 | } |
| 529 | if c.DiscardedJobRetentionPeriod < -1 { |
| 530 | return errors.New("DiscardedJobRetentionPeriod cannot be less than zero, except for -1 (infinite)") |
| 531 | } |
| 532 | if c.FetchCooldown < FetchCooldownMin { |
| 533 | return fmt.Errorf("FetchCooldown must be at least %s", FetchCooldownMin) |
| 534 | } |
| 535 | if c.FetchPollInterval < FetchPollIntervalMin { |
| 536 | return fmt.Errorf("FetchPollInterval must be at least %s", FetchPollIntervalMin) |
| 537 | } |
| 538 | if c.FetchPollInterval < c.FetchCooldown { |
| 539 | return fmt.Errorf("FetchPollInterval cannot be shorter than FetchCooldown (%s)", c.FetchCooldown) |
| 540 | } |
| 541 | if len(c.ID) > 100 { |
| 542 | return errors.New("ID cannot be longer than 100 characters") |
| 543 | } |
| 544 | if c.JobTimeout < -1 { |
| 545 | return errors.New("JobTimeout cannot be negative, except for -1 (infinite)") |
| 546 | } |
| 547 | if c.JobStuckThreshold < 0 { |
| 548 | return errors.New("JobStuckThreshold cannot be less than zero") |
| 549 | } |
| 550 | if c.MaxAttempts < 0 { |
| 551 | return errors.New("MaxAttempts cannot be less than zero") |
| 552 | } |
| 553 | if len(c.Middleware) > 0 && (len(c.JobInsertMiddleware) > 0 || len(c.WorkerMiddleware) > 0) { |
| 554 | return errors.New("only one of the pair JobInsertMiddleware/WorkerMiddleware or Middleware may be provided (Middleware is recommended, and may contain both job insert and worker middleware)") |
| 555 | } |
| 556 | if c.ReindexerTimeout < -1 { |
| 557 | return errors.New("ReindexerTimeout cannot be negative, except for -1 (infinite)") |
| 558 | } |
| 559 | if c.RescueStuckJobsAfter < 0 { |
| 560 | return errors.New("RescueStuckJobsAfter cannot be less than zero") |
| 561 | } |
| 562 | if c.RescueStuckJobsAfter < c.JobTimeout { |
| 563 | return errors.New("RescueStuckJobsAfter cannot be less than JobTimeout") |
| 564 | } |
| 565 | |
| 566 | // Max Postgres notification topic length is 63 and we prefix schema to |
| 567 | // notification topic, so whatever schema the user specifies must fit inside |
| 568 | // this convention. |
| 569 | maxSchemaLength := 63 - 1 - len(string(notifier.NotificationTopicLongest)) // -1 for the dot in `<schema>.<topic>` |
| 570 | if len(c.Schema) > maxSchemaLength { |
| 571 | return fmt.Errorf("Schema length must be less than or equal to %d characters", maxSchemaLength) |
| 572 | } |
| 573 | if c.Schema != "" && !postgresSchemaNameRE.MatchString(c.Schema) { |
| 574 | return errors.New("Schema name can only contain letters, numbers, and underscores, and must start with a letter or underscore") |
| 575 | } |
| 576 | |
| 577 | for queue, queueConfig := range c.Queues { |
| 578 | if err := queueConfig.validate(queue, c.FetchCooldown, c.FetchPollInterval); err != nil { |
| 579 | return err |