예제 #1
0
		logger = lagertest.NewTestLogger("test")
	})

	JustBeforeEach(func() {
		hasBecomeHealthyChannel := make(chan struct{}, 1000)
		hasBecomeHealthy = hasBecomeHealthyChannel

		workPool, err := workpool.NewWorkPool(numOfConcurrentMonitorSteps)
		Expect(err).NotTo(HaveOccurred())

		step = steps.NewMonitor(
			checkFunc,
			hasBecomeHealthyChannel,
			logger,
			clock,
			fakeStreamer,
			startTimeout,
			healthyInterval,
			unhealthyInterval,
			workPool,
		)
	})

	expectCheckAfterInterval := func(fakeStep *fakes.FakeStep, d time.Duration) {
		previousCheckCount := fakeStep.PerformCallCount()

		clock.Increment(d - 1*time.Microsecond)
		Consistently(fakeStep.PerformCallCount, 0.05).Should(Equal(previousCheckCount))

		clock.Increment(d)
		Eventually(fakeStep.PerformCallCount).Should(Equal(previousCheckCount + 1))
예제 #2
0
func (store *GardenStore) Run(logger lager.Logger, container executor.Container) error {
	logger = logger.Session("run", lager.Data{
		"guid": container.Guid,
	})
	logger.Info("started")
	defer logger.Info("finished")

	gardenContainer, err := store.lookup(logger, container.Guid)
	if err != nil {
		return err
	}
	logger.Debug("found-garden-container")

	if container.State != executor.StateCreated {
		logger.Debug("container-invalid-state-transition", lager.Data{
			"current_state":  container.State,
			"expected_state": executor.StateCreated,
		})

		transitionErr := executor.ErrInvalidTransition
		result := executor.ContainerRunResult{
			Failed:        true,
			FailureReason: transitionErr.Error(),
		}

		err := store.transitionToComplete(logger, gardenContainer, result)
		if err != nil {
			logger.Error("failed-transition-to-complete", err)
		}

		return transitionErr
	}

	logStreamer := log_streamer.New(
		container.LogConfig.Guid,
		container.LogConfig.SourceName,
		container.LogConfig.Index,
	)

	var setupStep, actionStep, monitorStep steps.Step

	if container.Setup != nil {
		setupStep = store.transformer.StepFor(
			logStreamer,
			container.Setup,
			gardenContainer,
			container.ExternalIP,
			container.Ports,
			logger.Session("setup"),
		)
	}

	actionStep = store.transformer.StepFor(
		logStreamer,
		container.Action,
		gardenContainer,
		container.ExternalIP,
		container.Ports,
		logger.Session("action"),
	)

	hasStartedRunning := make(chan struct{}, 1)

	if container.Monitor != nil {
		monitorStep = steps.NewMonitor(
			func() steps.Step {
				return store.transformer.StepFor(
					logStreamer,
					container.Monitor,
					gardenContainer,
					container.ExternalIP,
					container.Ports,
					logger.Session("monitor-run"),
				)
			},
			hasStartedRunning,
			logger.Session("monitor"),
			store.clock,
			logStreamer,
			time.Duration(container.StartTimeout)*time.Second,
			store.healthyMonitoringInterval,
			store.unhealthyMonitoringInterval,
			store.workPool,
		)
	}

	var longLivedAction steps.Step
	if monitorStep != nil {
		longLivedAction = steps.NewCodependent([]steps.Step{actionStep, monitorStep}, false)
	} else {
		longLivedAction = actionStep

		// this container isn't monitored, so we mark it running right away
		hasStartedRunning <- struct{}{}
	}

	var step steps.Step
	if setupStep != nil {
		step = steps.NewSerial([]steps.Step{setupStep, longLivedAction})
	} else {
		step = longLivedAction
	}

	store.runStepProcess(logger, step, hasStartedRunning, gardenContainer, container.Guid)

	return nil
}