github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/changestream/manifold.go (about)

     1  // Copyright 2023 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package changestream
     5  
     6  import (
     7  	"github.com/juju/clock"
     8  	"github.com/juju/errors"
     9  	"github.com/juju/worker/v3"
    10  	"github.com/juju/worker/v3/dependency"
    11  
    12  	coredatabase "github.com/juju/juju/core/database"
    13  	"github.com/juju/juju/worker/common"
    14  )
    15  
    16  // Logger represents the logging methods called.
    17  type Logger interface {
    18  	Errorf(message string, args ...interface{})
    19  	Warningf(message string, args ...interface{})
    20  	Infof(message string, args ...interface{})
    21  	Debugf(message string, args ...interface{})
    22  	Tracef(message string, args ...interface{})
    23  	IsTraceEnabled() bool
    24  }
    25  
    26  // EventQueueWorkerFn is an alias function that allows the creation of
    27  // EventQueueWorker.
    28  type EventQueueWorkerFn = func(coredatabase.TrackedDB, FileNotifier, clock.Clock, Logger) (EventQueueWorker, error)
    29  
    30  // ManifoldConfig defines the names of the manifolds on which a Manifold will
    31  // depend.
    32  type ManifoldConfig struct {
    33  	DBAccessor        string
    34  	FileNotifyWatcher string
    35  
    36  	Clock               clock.Clock
    37  	Logger              Logger
    38  	NewEventQueueWorker EventQueueWorkerFn
    39  }
    40  
    41  func (cfg ManifoldConfig) Validate() error {
    42  	if cfg.DBAccessor == "" {
    43  		return errors.NotValidf("empty DBAccessorName")
    44  	}
    45  	if cfg.FileNotifyWatcher == "" {
    46  		return errors.NotValidf("empty FileNotifyWatcherName")
    47  	}
    48  	if cfg.Clock == nil {
    49  		return errors.NotValidf("nil Clock")
    50  	}
    51  	if cfg.Logger == nil {
    52  		return errors.NotValidf("nil Logger")
    53  	}
    54  	if cfg.NewEventQueueWorker == nil {
    55  		return errors.NotValidf("nil NewEventQueueWorker")
    56  	}
    57  	return nil
    58  }
    59  
    60  // Manifold returns a dependency manifold that runs the changestream
    61  // worker, using the resource names defined in the supplied config.
    62  func Manifold(config ManifoldConfig) dependency.Manifold {
    63  	return dependency.Manifold{
    64  		Inputs: []string{
    65  			config.DBAccessor,
    66  			config.FileNotifyWatcher,
    67  		},
    68  		Output: changeStreamOutput,
    69  		Start: func(context dependency.Context) (worker.Worker, error) {
    70  			if err := config.Validate(); err != nil {
    71  				return nil, errors.Trace(err)
    72  			}
    73  
    74  			var dbGetter DBGetter
    75  			if err := context.Get(config.DBAccessor, &dbGetter); err != nil {
    76  				return nil, errors.Trace(err)
    77  			}
    78  
    79  			var fileNotifyWatcher FileNotifyWatcher
    80  			if err := context.Get(config.FileNotifyWatcher, &fileNotifyWatcher); err != nil {
    81  				return nil, errors.Trace(err)
    82  			}
    83  
    84  			cfg := WorkerConfig{
    85  				DBGetter:            dbGetter,
    86  				FileNotifyWatcher:   fileNotifyWatcher,
    87  				Clock:               config.Clock,
    88  				Logger:              config.Logger,
    89  				NewEventQueueWorker: config.NewEventQueueWorker,
    90  			}
    91  
    92  			w, err := newWorker(cfg)
    93  			if err != nil {
    94  				return nil, errors.Trace(err)
    95  			}
    96  			return w, nil
    97  		},
    98  	}
    99  }
   100  
   101  func changeStreamOutput(in worker.Worker, out interface{}) error {
   102  	if w, ok := in.(*common.CleanupWorker); ok {
   103  		in = w.Worker
   104  	}
   105  	w, ok := in.(*changeStreamWorker)
   106  	if !ok {
   107  		return errors.Errorf("in should be a *changeStreamWorker; got %T", in)
   108  	}
   109  
   110  	switch out := out.(type) {
   111  	case *ChangeStream:
   112  		var target ChangeStream = w
   113  		*out = target
   114  	default:
   115  		return errors.Errorf("out should be a *changestream.ChangeStream; got %T", out)
   116  	}
   117  	return nil
   118  }