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

add file change watch #534

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 115 additions & 12 deletions registry/file/backend.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,133 @@
// Package file implements a simple file based registry
// backend which reads the routes from a file once.
// backend which reads the routes from a file.
//file content like registry.static.routes = route add web-svc /test http://127.0.0.1:8082
//registry.file.path = /home/zjj/fabio.txt
//registry.file.noroutehtmlpath = /home/zjj/404.html
package file

import (
"io/ioutil"
"log"
"os"
"time"

"github.com/fabiolb/fabio/config"
"github.com/fabiolb/fabio/registry"
"github.com/fabiolb/fabio/registry/static"
)

type be struct {
cfg *config.File
routeMtime time.Time
norouteMtime time.Time
Routes string
NoRouteHTML string
Interval time.Duration
}

var (
zero time.Time
)

func NewBackend(cfg *config.File) (registry.Backend, error) {
routes, err := ioutil.ReadFile(cfg.RoutesPath)
if err != nil {
log.Println("[ERROR] Cannot read routes from ", cfg.RoutesPath)
b := &be{cfg: cfg, Interval: 2 * time.Second}
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you make the Interval configurable? See https://github.com/fabiolb/fabio/blob/master/config/load.go#L161 for an example.

Please also update the website documentation at

https://github.com/fabiolb/fabio/tree/master/docs/content/ref

Copy link
Author

Choose a reason for hiding this comment

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

update to commited.

if err := b.readRoute(); err != nil {
return nil, err
}
noroutehtml, err := ioutil.ReadFile(cfg.NoRouteHTMLPath)
if err != nil {
log.Println("[ERROR] Cannot read no route HTML from ", cfg.NoRouteHTMLPath)
if err := b.readNoRouteHtml(); err != nil {
return nil, err
}
staticCfg := &config.Static{
NoRouteHTML: string(noroutehtml),
Routes: string(routes),
return b, nil
}

func (b *be) readRoute() error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you merge the two readXXX functions into one like this

func readFile(path string, mtime time.Time) (string, error) {...}

finfo, err := os.Stat(b.cfg.RoutesPath)
if err != nil {
log.Println("[ERROR] Cannot read routes stat from ", b.cfg.RoutesPath)
return err
}

if b.routeMtime == zero || b.routeMtime != finfo.ModTime() {
b.routeMtime = finfo.ModTime()
routes, err := ioutil.ReadFile(b.cfg.RoutesPath)
if err != nil {
log.Println("[ERROR] Cannot read routes from ", b.cfg.RoutesPath)
return err
}
b.Routes = string(routes)
}
return nil
}

func (b *be) readNoRouteHtml() error {
if b.cfg.NoRouteHTMLPath != "" {
finfo, err := os.Stat(b.cfg.NoRouteHTMLPath)
if err != nil {
log.Println("[ERROR] Cannot read no route HTML stat from ", b.cfg.NoRouteHTMLPath)
return err
}
if b.norouteMtime == zero || b.norouteMtime != finfo.ModTime() {
b.norouteMtime = finfo.ModTime()
noroutehtml, err := ioutil.ReadFile(b.cfg.NoRouteHTMLPath)
if err != nil {
log.Println("[ERROR] Cannot read no route HTML from ", b.cfg.NoRouteHTMLPath)
return err
}
b.NoRouteHTML = string(noroutehtml)
}
}
return static.NewBackend(staticCfg)
return nil
}

func (b *be) Register(services []string) error {
return nil
}

func (b *be) Deregister(serviceName string) error {
return nil
}

func (b *be) DeregisterAll() error {
return nil
}

func (b *be) ManualPaths() ([]string, error) {
return nil, nil
}

func (b *be) ReadManual(string) (value string, version uint64, err error) {
return "", 0, nil
}

func (b *be) WriteManual(path string, value string, version uint64) (ok bool, err error) {
return false, nil
}

func (b *be) WatchServices() chan string {
ch := make(chan string, 1)
ch <- b.Routes
go func() {
for {
b.readRoute()
ch <- b.Routes
time.Sleep(b.Interval)
}
}()
return ch
}

func (b *be) WatchManual() chan string {
return make(chan string)
}

func (b *be) WatchNoRouteHTML() chan string {
ch := make(chan string, 1)
ch <- b.NoRouteHTML
go func() {
for {
b.readNoRouteHtml()
ch <- b.NoRouteHTML
time.Sleep(b.Interval)
}
}()
return ch
}