github.com/bazelbuild/rules_webtesting@v0.2.0/go/wtl/service/service.go (about)

     1  // Copyright 2016 Google Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package service provides the Service interface for managing the life-cycle
    16  // of a single binary.
    17  package service
    18  
    19  import (
    20  	"context"
    21  	"sync"
    22  
    23  	"github.com/bazelbuild/rules_webtesting/go/errors"
    24  	"github.com/bazelbuild/rules_webtesting/go/wtl/diagnostics"
    25  )
    26  
    27  // Base is a base struct for defining a service.
    28  type Base struct {
    29  	diagnostics.Diagnostics
    30  	name    string
    31  	mu      sync.RWMutex
    32  	started bool
    33  	stopped bool
    34  }
    35  
    36  // NewBase creates a new Base service with the given component name.
    37  func NewBase(name string, d diagnostics.Diagnostics) *Base {
    38  	return &Base{Diagnostics: d, name: name}
    39  }
    40  
    41  // Start makes this service as started, failing if it has already been started.
    42  func (b *Base) Start(context.Context) error {
    43  	b.mu.Lock()
    44  	defer b.mu.Unlock()
    45  	if b.started {
    46  		return errors.NewPermanent(b.Name(), "cannot be started; it has already been started once")
    47  	}
    48  	b.started = true
    49  	return nil
    50  }
    51  
    52  // Stop makes this service as stopped, failing if it hasn't been started or has already been stopped.
    53  func (b *Base) Stop(context.Context) error {
    54  	b.mu.Lock()
    55  	defer b.mu.Unlock()
    56  	if !b.started {
    57  		return errors.NewPermanent(b.Name(), "cannot be stopped; it was never started")
    58  	}
    59  	if b.stopped {
    60  		return errors.NewPermanent(b.Name(), "cannot be stopped; it was already stopped once")
    61  	}
    62  	b.stopped = true
    63  	return nil
    64  }
    65  
    66  // Healthy returns nil if this service has been started and has not been stopped.
    67  func (b *Base) Healthy(context.Context) error {
    68  	b.mu.RLock()
    69  	defer b.mu.RUnlock()
    70  	if !b.started {
    71  		return errors.NewPermanent(b.Name(), "has not been started")
    72  	}
    73  	if b.stopped {
    74  		return errors.NewPermanent(b.Name(), "has been stopped")
    75  	}
    76  	return nil
    77  }
    78  
    79  // Name returns the component name used in error messages.
    80  func (b *Base) Name() string {
    81  	return b.name
    82  }