github.com/qioalice/ekago/v3@v3.3.2-0.20221202205325-5c262d586ee4/ekadeath/death_private.go (about)

     1  // Copyright © 2019-2021. All rights reserved.
     2  // Author: Ilya Stroy.
     3  // Contacts: iyuryevich@pm.me, https://github.com/qioalice
     4  // License: https://opensource.org/licenses/MIT
     5  
     6  package ekadeath
     7  
     8  import (
     9  	"github.com/qioalice/ekago/v3/ekatyp"
    10  )
    11  
    12  type (
    13  	// destructorRegistered is a destructor descriptor.
    14  	// Each Reg() call converts passed destructor to that descriptor.
    15  	destructorRegistered = struct {
    16  		f              any  // can be DestructorSimple or DestructorWithExitCode
    17  		bindToExitCode int  // f will be called only if app is down with that exit code
    18  		callAnyway     bool // call no matter what exit code is
    19  	}
    20  )
    21  
    22  var (
    23  	// destructors is a LIFO stack that contains destructorRegistered objects.
    24  	destructors ekatyp.Stack
    25  )
    26  
    27  // reg registers each function from destructorsToBeRegistered as destructor
    28  // that will be called anyway if hasExitCodeBind is false (exitCode is ignored this way)
    29  // or will be called if Die with passed exitCode is called if hasExitCodeBind is true.
    30  func reg(hasExitCodeBind bool, exitCode int, destructorsToBeRegistered ...any) {
    31  	for _, destructor := range destructorsToBeRegistered {
    32  		if !valid(destructor) {
    33  			continue
    34  		}
    35  		destructors.Push(destructorRegistered{
    36  			f:              destructor,
    37  			bindToExitCode: exitCode,
    38  			callAnyway:     !hasExitCodeBind,
    39  		})
    40  	}
    41  }
    42  
    43  // valid reports whether d is valid destructor:
    44  // - it's type either DestructorSimple or DestructorWithExitCode,
    45  // - it's value is not nil.
    46  func valid(d any) bool {
    47  	switch d.(type) {
    48  	case DestructorSimple:
    49  		return d.(DestructorSimple) != nil
    50  	case DestructorWithExitCode:
    51  		return d.(DestructorWithExitCode) != nil
    52  	default:
    53  		return false
    54  	}
    55  }
    56  
    57  // invoke calls d with no passing arguments if d is DestructorSimple,
    58  // or passing exitCode if d is DestructorWithExitCode.
    59  func invoke(d any, exitCode int) {
    60  	switch d.(type) {
    61  	case DestructorSimple:
    62  		d.(DestructorSimple)()
    63  	case DestructorWithExitCode:
    64  		d.(DestructorWithExitCode)(exitCode)
    65  	}
    66  }