 9bdcbe0447
			
		
	
	9bdcbe0447
	
	
	
		
			
			Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			176 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			176 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (c) 2019 Uber Technologies, Inc.
 | |
| //
 | |
| // Permission is hereby granted, free of charge, to any person obtaining a copy
 | |
| // of this software and associated documentation files (the "Software"), to deal
 | |
| // in the Software without restriction, including without limitation the rights
 | |
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | |
| // copies of the Software, and to permit persons to whom the Software is
 | |
| // furnished to do so, subject to the following conditions:
 | |
| //
 | |
| // The above copyright notice and this permission notice shall be included in
 | |
| // all copies or substantial portions of the Software.
 | |
| //
 | |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | |
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | |
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | |
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | |
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | |
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | |
| // THE SOFTWARE.
 | |
| 
 | |
| package dig
 | |
| 
 | |
| import (
 | |
| 	"container/list"
 | |
| 	"fmt"
 | |
| 	"reflect"
 | |
| 	"strconv"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	_noValue    reflect.Value
 | |
| 	_errType    = reflect.TypeOf((*error)(nil)).Elem()
 | |
| 	_inPtrType  = reflect.TypeOf((*In)(nil))
 | |
| 	_inType     = reflect.TypeOf(In{})
 | |
| 	_outPtrType = reflect.TypeOf((*Out)(nil))
 | |
| 	_outType    = reflect.TypeOf(Out{})
 | |
| )
 | |
| 
 | |
| // Placeholder type placed in dig.In/dig.out to make their special nature
 | |
| // obvious in godocs.
 | |
| // Otherwise they will appear as plain empty structs.
 | |
| type digSentinel struct{}
 | |
| 
 | |
| // In may be embedded into structs to request dig to treat them as special
 | |
| // parameter structs. When a constructor accepts such a struct, instead of the
 | |
| // struct becoming a dependency for that constructor, all its fields become
 | |
| // dependencies instead. See the section on Parameter Objects in the
 | |
| // package-level documentation for more information.
 | |
| //
 | |
| // Fields of the struct may optionally be tagged to customize the behavior of
 | |
| // dig. The following tags are supported,
 | |
| //
 | |
| //	name        Requests a value with the same name and type from the
 | |
| //	            container. See Named Values for more information.
 | |
| //	optional    If set to true, indicates that the dependency is optional and
 | |
| //	            the constructor gracefully handles its absence.
 | |
| //	group       Name of the Value Group from which this field will be filled.
 | |
| //	            The field must be a slice type. See Value Groups in the
 | |
| //	            package documentation for more information.
 | |
| type In struct{ _ digSentinel }
 | |
| 
 | |
| // Out is an embeddable type that signals to dig that the returned
 | |
| // struct should be treated differently. Instead of the struct itself
 | |
| // becoming part of the container, all members of the struct will.
 | |
| 
 | |
| // Out may be embedded into structs to request dig to treat them as special
 | |
| // result structs. When a constructor returns such a struct, instead of the
 | |
| // struct becoming a result of the constructor, all its fields become results
 | |
| // of the constructor. See the section on Result Objects in the package-level
 | |
| // documentation for more information.
 | |
| //
 | |
| // Fields of the struct may optionally be tagged to customize the behavior of
 | |
| // dig. The following tags are supported,
 | |
| //
 | |
| //	name        Specifies the name of the value. Only a field on a dig.In
 | |
| //	            struct with the same 'name' annotation can receive this
 | |
| //	            value. See Named Values for more information.
 | |
| //	group       Name of the Value Group to which this field's value is being
 | |
| //	            sent. See Value Groups in the package documentation for more
 | |
| //	            information.
 | |
| type Out struct{ _ digSentinel }
 | |
| 
 | |
| func isError(t reflect.Type) bool {
 | |
| 	return t.Implements(_errType)
 | |
| }
 | |
| 
 | |
| // IsIn checks whether the given struct is a dig.In struct. A struct qualifies
 | |
| // as a dig.In struct if it embeds the dig.In type or if any struct that it
 | |
| // embeds is a dig.In struct. The parameter may be the reflect.Type of the
 | |
| // struct rather than the struct itself.
 | |
| //
 | |
| // A struct MUST qualify as a dig.In struct for its fields to be treated
 | |
| // specially by dig.
 | |
| //
 | |
| // See the documentation for dig.In for a comprehensive list of supported
 | |
| // tags.
 | |
| func IsIn(o interface{}) bool {
 | |
| 	return embedsType(o, _inType)
 | |
| }
 | |
| 
 | |
| // IsOut checks whether the given struct is a dig.Out struct. A struct
 | |
| // qualifies as a dig.Out struct if it embeds the dig.Out type or if any
 | |
| // struct that it embeds is a dig.Out struct. The parameter may be the
 | |
| // reflect.Type of the struct rather than the struct itself.
 | |
| //
 | |
| // A struct MUST qualify as a dig.Out struct for its fields to be treated
 | |
| // specially by dig.
 | |
| //
 | |
| // See the documentation for dig.Out for a comprehensive list of supported
 | |
| // tags.
 | |
| func IsOut(o interface{}) bool {
 | |
| 	return embedsType(o, _outType)
 | |
| }
 | |
| 
 | |
| // Returns true if t embeds e or if any of the types embedded by t embed e.
 | |
| func embedsType(i interface{}, e reflect.Type) bool {
 | |
| 	// TODO: this function doesn't consider e being a pointer.
 | |
| 	// given `type A foo { *In }`, this function would return false for
 | |
| 	// embedding dig.In, which makes for some extra error checking in places
 | |
| 	// that call this function. Might be worthwhile to consider reflect.Indirect
 | |
| 	// usage to clean up the callers.
 | |
| 
 | |
| 	if i == nil {
 | |
| 		return false
 | |
| 	}
 | |
| 
 | |
| 	// maybe it's already a reflect.Type
 | |
| 	t, ok := i.(reflect.Type)
 | |
| 	if !ok {
 | |
| 		// take the type if it's not
 | |
| 		t = reflect.TypeOf(i)
 | |
| 	}
 | |
| 
 | |
| 	// We are going to do a breadth-first search of all embedded fields.
 | |
| 	types := list.New()
 | |
| 	types.PushBack(t)
 | |
| 	for types.Len() > 0 {
 | |
| 		t := types.Remove(types.Front()).(reflect.Type)
 | |
| 
 | |
| 		if t == e {
 | |
| 			return true
 | |
| 		}
 | |
| 
 | |
| 		if t.Kind() != reflect.Struct {
 | |
| 			continue
 | |
| 		}
 | |
| 
 | |
| 		for i := 0; i < t.NumField(); i++ {
 | |
| 			f := t.Field(i)
 | |
| 			if f.Anonymous {
 | |
| 				types.PushBack(f.Type)
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// If perf is an issue, we can cache known In objects and Out objects in a
 | |
| 	// map[reflect.Type]struct{}.
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| // Checks if a field of an In struct is optional.
 | |
| func isFieldOptional(f reflect.StructField) (bool, error) {
 | |
| 	tag := f.Tag.Get(_optionalTag)
 | |
| 	if tag == "" {
 | |
| 		return false, nil
 | |
| 	}
 | |
| 
 | |
| 	optional, err := strconv.ParseBool(tag)
 | |
| 	if err != nil {
 | |
| 		err = newErrInvalidInput(
 | |
| 			fmt.Sprintf("invalid value %q for %q tag on field %v", tag, _optionalTag, f.Name), err)
 | |
| 	}
 | |
| 
 | |
| 	return optional, err
 | |
| }
 |