Example #1
0
func (s *ManifoldSuite) TestOutputSuccess(c *gc.C) {
	w := s.mustStartManifold(c)

	var stTracker workerstate.StateTracker
	err := s.manifold.Output(w, &stTracker)
	c.Assert(err, jc.ErrorIsNil)

	st, err := stTracker.Use()
	c.Assert(err, jc.ErrorIsNil)
	c.Check(st, gc.Equals, s.State)
	c.Assert(stTracker.Done(), jc.ErrorIsNil)

	// Ensure State is closed when the worker is done.
	checkStop(c, w)
	assertStateClosed(c, s.State)
}
Example #2
0
func (s *ManifoldSuite) TestStateStillInUse(c *gc.C) {
	w := s.mustStartManifold(c)

	var stTracker workerstate.StateTracker
	err := s.manifold.Output(w, &stTracker)
	c.Assert(err, jc.ErrorIsNil)

	st, err := stTracker.Use()
	c.Assert(err, jc.ErrorIsNil)

	// Close the worker while the State is still in use.
	checkStop(c, w)
	assertStateNotClosed(c, st)

	// Now signal that the State is no longer needed.
	c.Assert(stTracker.Done(), jc.ErrorIsNil)
	assertStateClosed(c, st)
}
Example #3
0
// StateWorkersManifold starts workers that rely on a *state.State
// using a function provided to it.
//
// This manifold exists to start State-using workers which have not
// yet been ported to work directly with the dependency engine. Once
// all state workers started by StartStateWorkers have been migrated
// to the dependency engine, this manifold can be removed.
func StateWorkersManifold(config StateWorkersConfig) dependency.Manifold {
	return dependency.Manifold{
		Inputs: []string{
			config.StateName,
		},
		Start: func(context dependency.Context) (worker.Worker, error) {
			if config.StartStateWorkers == nil {
				return nil, errors.New("StartStateWorkers not specified")
			}

			var stTracker workerstate.StateTracker
			if err := context.Get(config.StateName, &stTracker); err != nil {
				return nil, err
			}

			st, err := stTracker.Use()
			if err != nil {
				return nil, errors.Annotate(err, "acquiring state")
			}

			w, err := config.StartStateWorkers(st)
			if err != nil {
				stTracker.Done()
				return nil, errors.Annotate(err, "worker startup")
			}

			// When the state workers are done, indicate that we no
			// longer need the State.
			go func() {
				w.Wait()
				stTracker.Done()
			}()

			return w, nil
		},
	}
}