comentado código

master
dev 1 year ago
parent 8c84ab60fc
commit 2e1316e5b7

@ -0,0 +1,92 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// 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.
//
// =============================================================================
// Date Create 19/05/2025
// =============================================================================
package errs
import (
"fmt"
"sync"
)
type (
Dispatcher struct {
mu sync.RWMutex
processors map[string]Processor
formatters map[string]Formatter
bufferSize int
cacheMu sync.Mutex
cacheEnable map[string]struct{}
formatCache map[string]map[uintptr][]byte
}
DispatcherFnc func (dispatcher *Dispatcher) error
)
func NewDispatcher(options ...DispatcherFnc) (*Dispatcher,error) {
dp := &Dispatcher{
processors : make(map[string]Processor),
formatters : make(map[string]Formatter),
formatCache: make(map[string]map[uintptr][]byte),
cacheEnable: make(map[string]struct{}),
}
for _,o := range options {
if e := o(dp); e != nil {
return nil,e
}
}
return dp,nil
}
func (d *Dispatcher) RegisterProcessor(processor Processor, options ...ProcessorEntryFnc) error {
d.mu.Lock()
defer d.mu.Unlock()
if processor == nil {
return CreateParamNilErr("processor")
}
if _,ex := d.formatters[processor.FormatterID()]; !ex {
//
//todo create newerror formatter_not_registered
}
if _,ex := d.processors[processor.ID()]; ex {
//
//todo create newerror processor_registered
}
pe,er := NewProcessorEntry(options...)
if er != nil {
return er
}
d.processors[processor.ID()] = pe
return nil
}

@ -0,0 +1,47 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// 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.
//
// =============================================================================
// Date Create 20/05/2025
// =============================================================================
package errs
type (
Formatter interface {
Format (err error) ([]byte,error)
}
FormatFnc func (error) ([]byte,error)
)
func (f FormatFnc) Format (err error) ([]byte,error) { return f(err) }

@ -0,0 +1,43 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// 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.
//
// =============================================================================
// Date Create 19/05/2025
// =============================================================================
package errs
type (
Processor interface {
ID () string
FormatterID () string
CanProcess (err error) bool
Process (data []byte) error
State () ProcessorState
}
)

@ -0,0 +1,55 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// 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.
//
// =============================================================================
// Date Create 20/05/2025
// =============================================================================
package errs
import "time"
type (
ProcessorEntry struct {
processor Processor
channel chan error
state ProcessorState
failures int
maxFailures int
blockedTime time.Time
blockTime time.Time
errors []error
}
ProcessorEntryFnc func(*ProcessorEntry) error
)
func NewProcessorEntry (options...ProcessorEntryFnc) (*ProcessorEntry,error) {
pe := &ProcessorEntry {
}
return pe,nil
}

@ -0,0 +1,36 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// 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.
//
// =============================================================================
// Date Create 19/05/2025
// =============================================================================
package errs
type ProcessorState uint8

@ -169,7 +169,7 @@ if errsList.Any() {
---
**Repositorio oficial:** [Active-Go Core](https://github.com/active-go/core)
**Documentación:** [https://docs.active-go.com/errors](https://docs.active-go.com/errors)
**Documentación:** [https://docs.active-go.com/errors](https://g.activething.com/errors)
---

@ -1,3 +1,4 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
@ -26,51 +27,64 @@
// Date Create 13/05/2025
// =============================================================================
// Package excs provides utilities for capturing and working with execution contexts,
// primarily focused on stack traces. This package is used by the errs package
// to include stack trace information in structured errors.
package excs
import (
"runtime"
)
// Constantes utilizadas para la configuración y manejo de stack traces
// Constants used for stack trace configuration and handling.
const (
// stackSkipFrames define cuántos frames iniciales se omiten al capturar el stack
// Se omiten 2 frames para excluir las llamadas internas del sistema
// stackSkipFrames defines how many initial frames are skipped when capturing the stack.
// 2 frames are skipped to exclude internal system calls (runtime.Callers and this function).
stackSkipFrames = 2
// stackMaxFrames define el número máximo de frames que se capturarán
// Limita la profundidad del stack trace a 32 frames
// stackMaxFrames defines the maximum number of frames that will be captured.
// Limits the depth of the stack trace to 32 frames by default.
stackMaxFrames = 32
)
// Stack is a slice of program counters, representing a captured stack trace.
type Stack []uintptr
// CreateStack captures the current execution stack trace.
// It takes an offset (number of frames to skip in addition to the default)
// and maxFrames (maximum number of frames to capture).
// Returns a Stack slice containing the captured program counters.
func CreateStack(offset, maxFrames int) Stack {
// Create a slice to store program counters with maximum capacity
// Determine the effective maximum number of frames to capture.
mx := stackMaxFrames
if maxFrames > 0 {
mx = maxFrames
}
// Create a slice to store program counters with maximum capacity.
ls := make([]uintptr, mx)
// Ensure offset is not negative
// Ensure offset is not negative.
if offset < 0 {
offset = 0
}
// Capture the stack trace using runtime.Callers
// cn will contain the actual number of frames captured
// Capture the stack trace using runtime.Callers.
// runtime.Callers fills the slice 'ls' with program counters,
// skipping 'offset + stackSkipFrames' frames.
// 'cn' will contain the actual number of frames captured.
cn := runtime.Callers(offset+stackSkipFrames, ls)
// Return only the slice containing valid program counters
// Return only the slice containing valid program counters (up to 'cn').
return ls[:cn]
}
// Frames converts the Stack (slice of program counters) into a slice of StackFrame objects.
// Each StackFrame provides detailed information about a single frame in the stack.
func (s Stack) Frames() []StackFrame {
// Create a slice to store Frame objects
// Create a slice to store StackFrame objects with the same length as the stack.
f := make([]StackFrame, len(s))
// Convert each program counter to a Frame object
// Convert each program counter to a StackFrame object.
for i, p := range s {
f[i] = CreateStackFrame(p)
}

@ -37,79 +37,108 @@ import (
)
const (
// stackUnknownInfo es el valor por defecto cuando no se puede obtener
// información sobre un frame del stack
// stackUnknownInfo is the default value when information about a stack frame cannot be obtained.
stackUnknownInfo = "???"
)
type (
// StackFrame represents a single frame in a stack trace.
// It contains detailed information about the function call at that point.
StackFrame struct {
// LineNumber is the line number in the source file where this frame was created
// LineNumber is the line number in the source file where this frame was created.
LineNumber int
// File is the full path to the source file containing this frame
// File is the full path to the source file containing this frame.
File string
// FuncName is the name of the function where this frame was created,
// with any receiver types removed
// with any receiver types removed.
FuncName string
// Package is the full package path where this frame was created
// Package is the full package path where this frame was created.
Package string
// Counter is the program counter address for this frame
// Counter is the program counter address for this frame.
Counter uintptr
// files is an internal cache of file contents
// files is an internal cache of file contents.
// Note: This field is present but not used in the current implementation of SourceLine.
files map[string][]byte
}
)
// CreateStackFrame creates a new StackFrame from a program counter address.
// It uses runtime information to populate the frame details.
// Returns an empty StackFrame if the counter is 0.
func CreateStackFrame(counter uintptr) StackFrame {
sf := StackFrame{}
if counter == 0 {
return sf
}
sf.Counter = counter
// Get runtime.Func for the program counter.
fn := runtime.FuncForPC(counter)
// Extract package and function name.
sf.Package, sf.FuncName = packageAndName(fn)
// Get file and line number. Note: counter - 1 is used to get the call site.
sf.File, sf.LineNumber = fn.FileLine(counter - 1)
return sf
}
// SourceLine attempts to retrieve the source code line for this stack frame.
// It reads the source file and returns the content of the line specified by LineNumber.
// Returns stackUnknownInfo if the line number is invalid or an error occurs while reading the file.
func (f StackFrame) SourceLine() (string, error) {
// Return unknown info if line number is not valid.
if f.LineNumber <= 0 {
return stackUnknownInfo, nil
}
// Open the source file.
file, err := os.Open(f.File)
if err != nil {
return "", err
return "", err // Return error if file cannot be opened.
}
defer file.Close() // Ensure the file is closed.
scanner := bufio.NewScanner(file)
currentLine := 1
// Scan the file line by line.
for scanner.Scan() {
// If the current line matches the frame's line number.
if currentLine == f.LineNumber {
// Return the trimmed line content as a string.
return string(bytes.Trim(scanner.Bytes(), " \t")), nil
}
currentLine++
}
_ = file.Close()
// Check for scanner errors.
if err := scanner.Err(); err != nil {
return "", err
return "", err // Return scanner error.
}
// If the line number was not found (e.g., file shorter than expected).
return stackUnknownInfo, nil
}
// packageAndName extracts the package path and function name from a runtime.Func.
// It handles different naming conventions, including methods.
func packageAndName(fn *runtime.Func) (string, string) {
nm := fn.Name()
pg := ""
nm := fn.Name() // Get the full name, e.g., "main.(*MyType).MyMethod" or "main.myFunction"
pg := "" // Initialize package path
// Find the last slash, which separates package path components.
if ls := strings.LastIndex(nm, "/"); ls >= 0 {
pg = nm[:ls] + "/"
nm = nm[ls+1:]
pg = nm[:ls] + "/" // Extract the path part
nm = nm[ls+1:] // Keep the rest of the name
}
// Find the first dot after the last slash, which separates package name from function name.
if pd := strings.Index(nm, "."); pd >= 0 {
pg += nm[:pd]
nm = nm[pd+1:]
pg += nm[:pd] // Add the package name to the path
nm = nm[pd+1:] // Keep the function name
}
// Replace the Go internal method separator '·' with '.' for readability.
return pg, strings.Replace(nm, "·", ".", -1)
}

Loading…
Cancel
Save

Powered by TurnKey Linux.