github.com/gedevops/x@v1.0.3/watcherx/definitions.go (about)

     1  package watcherx
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/url"
     7  )
     8  
     9  type (
    10  	errSchemeUnknown struct {
    11  		scheme string
    12  	}
    13  	EventChannel chan Event
    14  	Watcher      interface {
    15  		// DispatchNow fires the watcher and causes an event.
    16  		//
    17  		// WARNING: The returned channel must be read or no further events will
    18  		// be propagated due to a deadlock.
    19  		DispatchNow() (<-chan int, error)
    20  	}
    21  	dispatcher struct {
    22  		trigger chan struct{}
    23  		done    chan int
    24  	}
    25  )
    26  
    27  var (
    28  	// ErrSchemeUnknown is just for checking with errors.Is()
    29  	ErrSchemeUnknown     = &errSchemeUnknown{}
    30  	ErrWatcherNotRunning = fmt.Errorf("watcher is not running")
    31  )
    32  
    33  func (e *errSchemeUnknown) Is(other error) bool {
    34  	_, ok := other.(*errSchemeUnknown)
    35  	return ok
    36  }
    37  
    38  func (e *errSchemeUnknown) Error() string {
    39  	return fmt.Sprintf("unknown scheme '%s' to watch", e.scheme)
    40  }
    41  
    42  func newDispatcher() *dispatcher {
    43  	return &dispatcher{
    44  		trigger: make(chan struct{}),
    45  		done:    make(chan int),
    46  	}
    47  }
    48  
    49  func (d *dispatcher) DispatchNow() (<-chan int, error) {
    50  	if d.trigger == nil {
    51  		return nil, ErrWatcherNotRunning
    52  	}
    53  	d.trigger <- struct{}{}
    54  	return d.done, nil
    55  }
    56  
    57  func Watch(ctx context.Context, u *url.URL, c EventChannel) (Watcher, error) {
    58  	switch u.Scheme {
    59  	// see urlx.Parse for why the empty string is also file
    60  	case "file", "":
    61  		return WatchFile(ctx, u.Path, c)
    62  	case "ws":
    63  		return WatchWebsocket(ctx, u, c)
    64  	}
    65  	return nil, &errSchemeUnknown{u.Scheme}
    66  }