gopkg.in/goose.v2@v2.0.1/testservices/hook/service.go (about)

     1  package hook
     2  
     3  type TestService struct {
     4  	ServiceControl
     5  	// Hooks to run when specified control points are reached in the service business logic.
     6  	ControlHooks map[string]ControlProcessor
     7  }
     8  
     9  // ControlProcessor defines a function that is run when a specified control point is reached in the service
    10  // business logic. The function receives the service instance so internal state can be inspected, plus for any
    11  // arguments passed to the currently executing service function.
    12  type ControlProcessor func(sc ServiceControl, args ...interface{}) error
    13  
    14  // ControlHookCleanup defines a function used to remove a control hook.
    15  type ControlHookCleanup func()
    16  
    17  // ServiceControl instances allow hooks to be registered for execution at the specified point of execution.
    18  // The control point name can be a function name or a logical execution point meaningful to the service.
    19  // If name is "", the hook for the currently executing function is executed.
    20  // Returns a function which can be used to remove the hook.
    21  type ServiceControl interface {
    22  	RegisterControlPoint(name string, controller ControlProcessor) ControlHookCleanup
    23  }
    24  
    25  // ProcessControlHook retrieves the ControlProcessor for the specified hook name and runs it, returning any error.
    26  // Use it like this to invoke a hook registered for some arbitrary control point:
    27  // if err := n.ProcessControlHook("foobar", <serviceinstance>, <somearg1>, <somearg2>); err != nil {
    28  //     return err
    29  // }
    30  func (s *TestService) ProcessControlHook(hookName string, sc ServiceControl, args ...interface{}) error {
    31  	if s.ControlHooks == nil {
    32  		return nil
    33  	}
    34  	if hook, ok := s.ControlHooks[hookName]; ok {
    35  		return hook(sc, args...)
    36  	}
    37  	return nil
    38  }
    39  
    40  // ProcessFunctionHook runs the ControlProcessor for the current function, returning any error.
    41  // Use it like this:
    42  // if err := n.ProcessFunctionHook(<serviceinstance>, <somearg1>, <somearg2>); err != nil {
    43  //     return err
    44  // }
    45  func (s *TestService) ProcessFunctionHook(sc ServiceControl, args ...interface{}) error {
    46  	hookName := s.currentServiceMethodName()
    47  	return s.ProcessControlHook(hookName, sc, args...)
    48  }
    49  
    50  // RegisterControlPoint assigns the specified controller to the named hook. If nil, any existing controller for the
    51  // hook is removed.
    52  // hookName is the name of a function on the service or some arbitrarily named control point.
    53  func (s *TestService) RegisterControlPoint(hookName string, controller ControlProcessor) ControlHookCleanup {
    54  	if s.ControlHooks == nil {
    55  		s.ControlHooks = make(map[string]ControlProcessor)
    56  	}
    57  	if controller == nil {
    58  		delete(s.ControlHooks, hookName)
    59  	} else {
    60  		s.ControlHooks[hookName] = controller
    61  	}
    62  	return func() {
    63  		s.RegisterControlPoint(hookName, nil)
    64  	}
    65  }