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

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package raftflag
     5  
     6  import (
     7  	"github.com/hashicorp/raft"
     8  	"github.com/juju/errors"
     9  	"gopkg.in/juju/worker.v1"
    10  	"gopkg.in/juju/worker.v1/dependency"
    11  
    12  	"github.com/juju/juju/cmd/jujud/agent/engine"
    13  )
    14  
    15  // ManifoldConfig holds the information necessary to run a raftflag.Worker in
    16  // a dependency.Engine.
    17  type ManifoldConfig struct {
    18  	RaftName string
    19  
    20  	NewWorker func(Config) (worker.Worker, error)
    21  }
    22  
    23  func (config ManifoldConfig) start(context dependency.Context) (worker.Worker, error) {
    24  	var r *raft.Raft
    25  	if err := context.Get(config.RaftName, &r); err != nil {
    26  		return nil, errors.Trace(err)
    27  	}
    28  
    29  	flag, err := config.NewWorker(Config{Raft: r})
    30  	if err != nil {
    31  		return nil, errors.Trace(err)
    32  	}
    33  	return wrappedWorker{flag}, nil
    34  }
    35  
    36  // wrappedWorker wraps a flag worker, translating ErrRefresh into
    37  // dependency.ErrBounce.
    38  type wrappedWorker struct {
    39  	worker.Worker
    40  }
    41  
    42  // Wait is part of the worker.Worker interface.
    43  func (w wrappedWorker) Wait() error {
    44  	err := w.Worker.Wait()
    45  	if err == ErrRefresh {
    46  		err = dependency.ErrBounce
    47  	}
    48  	return err
    49  }
    50  
    51  // Manifold returns a dependency.Manifold that will run a FlagWorker and
    52  // expose it to clients as a engine.Flag resource.
    53  func Manifold(config ManifoldConfig) dependency.Manifold {
    54  	return dependency.Manifold{
    55  		Inputs: []string{
    56  			config.RaftName,
    57  		},
    58  		Start: config.start,
    59  		Output: func(in worker.Worker, out interface{}) error {
    60  			if w, ok := in.(wrappedWorker); ok {
    61  				in = w.Worker
    62  			}
    63  			return engine.FlagOutput(in, out)
    64  		},
    65  	}
    66  }