 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>
		
			
				
	
	
		
			109 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package obj
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"reflect"
 | |
| 
 | |
| 	"github.com/polydawn/refmt/obj/atlas"
 | |
| 	. "github.com/polydawn/refmt/tok"
 | |
| )
 | |
| 
 | |
| type marshalMachineStructAtlas struct {
 | |
| 	cfg *atlas.AtlasEntry // set on initialization
 | |
| 
 | |
| 	target_rv reflect.Value
 | |
| 	index     int           // Progress marker
 | |
| 	value_rv  reflect.Value // Next value (or nil if next step is key).
 | |
| }
 | |
| 
 | |
| func (mach *marshalMachineStructAtlas) Reset(slab *marshalSlab, rv reflect.Value, _ reflect.Type) error {
 | |
| 	mach.target_rv = rv
 | |
| 	mach.index = -1
 | |
| 	mach.value_rv = reflect.Value{}
 | |
| 	slab.grow() // we'll reuse the same row for all fields
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (mach *marshalMachineStructAtlas) Step(driver *Marshaller, slab *marshalSlab, tok *Token) (done bool, err error) {
 | |
| 	//fmt.Printf("--step on %#v: i=%d/%d v=%v\n", mach.target_rv, mach.index, len(mach.cfg.Fields), mach.value)
 | |
| 
 | |
| 	// Check boundaries and do the special steps or either start or end.
 | |
| 	nEntries := len(mach.cfg.StructMap.Fields)
 | |
| 	if mach.index < 0 {
 | |
| 		tok.Type = TMapOpen
 | |
| 		tok.Length = countEmittableStructFields(mach.cfg, mach.target_rv)
 | |
| 		tok.Tagged = mach.cfg.Tagged
 | |
| 		tok.Tag = mach.cfg.Tag
 | |
| 		mach.index++
 | |
| 		return false, nil
 | |
| 	}
 | |
| 	if mach.index == nEntries {
 | |
| 		tok.Type = TMapClose
 | |
| 		mach.index++
 | |
| 		slab.release()
 | |
| 		return true, nil
 | |
| 	}
 | |
| 	if mach.index > nEntries {
 | |
| 		return true, fmt.Errorf("invalid state: entire struct (%d fields) already consumed", nEntries)
 | |
| 	}
 | |
| 
 | |
| 	// If value loaded from last step, recurse into handling that.
 | |
| 	fieldEntry := mach.cfg.StructMap.Fields[mach.index]
 | |
| 	if mach.value_rv != (reflect.Value{}) {
 | |
| 		child_rv := mach.value_rv
 | |
| 		mach.index++
 | |
| 		mach.value_rv = reflect.Value{}
 | |
| 		return false, driver.Recurse(
 | |
| 			tok,
 | |
| 			child_rv,
 | |
| 			fieldEntry.Type,
 | |
| 			slab.yieldMachine(fieldEntry.Type),
 | |
| 		)
 | |
| 	}
 | |
| 
 | |
| 	// If value was nil, that indicates we're supposed to pick the value and yield a key.
 | |
| 	//  We have to look ahead to the value because if it's zero and tagged as
 | |
| 	//  omitEmpty, then we have to skip emitting the key as well.
 | |
| 	for fieldEntry.Ignore {
 | |
| 		mach.index++
 | |
| 		if mach.index == nEntries {
 | |
| 			tok.Type = TMapClose
 | |
| 			mach.index++
 | |
| 			slab.release()
 | |
| 			return true, nil
 | |
| 		}
 | |
| 		fieldEntry = mach.cfg.StructMap.Fields[mach.index]
 | |
| 	}
 | |
| 	mach.value_rv = fieldEntry.ReflectRoute.TraverseToValue(mach.target_rv)
 | |
| 	if fieldEntry.OmitEmpty && isEmptyValue(mach.value_rv) {
 | |
| 		mach.value_rv = reflect.Value{}
 | |
| 		mach.index++
 | |
| 		return mach.Step(driver, slab, tok)
 | |
| 	}
 | |
| 	tok.Type = TString
 | |
| 	tok.Str = fieldEntry.SerialName
 | |
| 	return false, nil
 | |
| }
 | |
| 
 | |
| // Count how many fields in a struct should actually be marshalled.
 | |
| // Fields that are tagged omitEmpty and are isEmptyValue are not counted, and
 | |
| // StructMapEntry used to flag ignored fields unmarshalling never count, so
 | |
| // this number may be less than the number of fields in the AtlasEntry.StructMap.
 | |
| func countEmittableStructFields(cfg *atlas.AtlasEntry, target_rv reflect.Value) int {
 | |
| 	total := 0
 | |
| 	for _, fieldEntry := range cfg.StructMap.Fields {
 | |
| 		if fieldEntry.Ignore {
 | |
| 			continue
 | |
| 		}
 | |
| 		if !fieldEntry.OmitEmpty {
 | |
| 			total++
 | |
| 			continue
 | |
| 		}
 | |
| 		if !isEmptyValue(fieldEntry.ReflectRoute.TraverseToValue(target_rv)) {
 | |
| 			total++
 | |
| 			continue
 | |
| 		}
 | |
| 	}
 | |
| 	return total
 | |
| }
 |