github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/centralhub/manifold.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package centralhub
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/pubsub"
     9  	"gopkg.in/juju/worker.v1"
    10  	"gopkg.in/juju/worker.v1/dependency"
    11  	"gopkg.in/tomb.v2"
    12  )
    13  
    14  // ManifoldConfig provides the dependencies for Manifold.
    15  type ManifoldConfig struct {
    16  	StateConfigWatcherName string
    17  	// TODO: remove Hub config when apiserver and peergrouper can depend on
    18  	// this hub.
    19  	Hub *pubsub.StructuredHub
    20  }
    21  
    22  // Manifold returns a manifold whose worker simply provides the central hub.
    23  // This hub is a dependency for any other workers that need the hub.
    24  func Manifold(config ManifoldConfig) dependency.Manifold {
    25  	return dependency.Manifold{
    26  		Inputs: []string{
    27  			config.StateConfigWatcherName,
    28  		},
    29  		Start: func(context dependency.Context) (worker.Worker, error) {
    30  			// Confirm we're running in a state server by asking the
    31  			// stateconfigwatcher manifold.
    32  			var haveStateConfig bool
    33  			if err := context.Get(config.StateConfigWatcherName, &haveStateConfig); err != nil {
    34  				return nil, err
    35  			}
    36  			if !haveStateConfig {
    37  				return nil, dependency.ErrMissing
    38  			}
    39  
    40  			if config.Hub == nil {
    41  				return nil, errors.NotValidf("missing hub")
    42  			}
    43  
    44  			w := &centralHub{
    45  				hub: config.Hub,
    46  			}
    47  			w.tomb.Go(func() error {
    48  				<-w.tomb.Dying()
    49  				return nil
    50  			})
    51  			return w, nil
    52  		},
    53  		Output: outputFunc,
    54  	}
    55  }
    56  
    57  // outputFunc extracts a pubsub.Hub from a *centralHub.
    58  func outputFunc(in worker.Worker, out interface{}) error {
    59  	inWorker, _ := in.(*centralHub)
    60  	if inWorker == nil {
    61  		return errors.Errorf("in should be a %T; got %T", inWorker, in)
    62  	}
    63  
    64  	switch outPointer := out.(type) {
    65  	case **pubsub.StructuredHub:
    66  		*outPointer = inWorker.hub
    67  	default:
    68  		return errors.Errorf("out should be *pubsub.StructuredHub; got %T", out)
    69  	}
    70  	return nil
    71  }
    72  
    73  type centralHub struct {
    74  	tomb tomb.Tomb
    75  	hub  *pubsub.StructuredHub
    76  }
    77  
    78  // Kill is part of the worker.Worker interface.
    79  func (w *centralHub) Kill() {
    80  	w.tomb.Kill(nil)
    81  }
    82  
    83  // Wait is part of the worker.Worker interface.
    84  func (w *centralHub) Wait() error {
    85  	return w.tomb.Wait()
    86  }