Skip to content

Frequently Asked Questions

Common questions about TinySystems development and usage.


General

What is TinySystems?

TinySystems is a Kubernetes-native, flow-based application development platform. It allows you to build applications by connecting reusable components in visual flows, with each component running as a Kubernetes resource.

How does TinySystems differ from other workflow tools?

Key differences:

  • Kubernetes-native: Components run as Kubernetes resources, leveraging K8s for scaling, networking, and state
  • Go-based SDK: Write components in Go with full type safety
  • Blocking execution: Synchronous message passing ensures reliable processing
  • CR-based state: State propagation via Custom Resources enables horizontal scaling

What can I build with TinySystems?

  • API integrations and data pipelines
  • Webhook processors and event handlers
  • Scheduled automation tasks
  • Data transformation workflows
  • Multi-service orchestration
  • Internal tools and dashboards

Development

How do I create a new component?

  1. Create a Go struct implementing module.Component
  2. Implement GetInfo(), Ports(), Handle(), and Instance()
  3. Register with a module
  4. Build and deploy

See the Component Interface guide.

Why does my component need to implement Instance()?

Instance() returns a fresh component instance for each TinyNode. This ensures:

  • No shared state between nodes
  • Clean initialization
  • Proper garbage collection
go
func (c *Component) Instance() module.Component {
    return &Component{}
}

How do I add configuration to my component?

Create a Settings struct and expose it via the _settings port:

go
type Settings struct {
    Timeout string `json:"timeout" default:"30s"`
}

func (c *Component) Ports() []module.Port {
    return []module.Port{
        {
            Name:          v1alpha1.SettingsPort,
            Source:        true,
            Configuration: Settings{},
        },
    }
}

Why isn't my struct tag appearing in the UI?

Check that:

  1. The field is exported (capitalized)
  2. The json tag is present
  3. The tag syntax is correct (no spaces around =)
  4. You're using supported tags (title, description, required, etc.)

How do I debug component execution?

  1. Use standard Go logging in your component
  2. Check pod logs: kubectl logs <pod>
  3. Enable debug mode in settings
  4. Use the TinySystems dashboard for flow visualization

Execution Model

Why does output() block?

The blocking model provides:

  • Backpressure: Slow consumers prevent fast producers from overwhelming the system
  • Error propagation: Errors bubble up through the call chain
  • Reliable delivery: Messages aren't lost to buffer overflows
  • Predictable execution: Easy to reason about flow behavior

Can I send messages without blocking?

Yes, wrap in a goroutine:

go
go output(ctx, "notification", msg)

But be careful:

  • You lose error handling
  • No backpressure
  • The component may complete before the message is delivered

What happens when downstream processing fails?

The error propagates back through the output() call chain:

go
err := output(ctx, "result", data)
if err != nil {
    // Downstream failed - handle the error
    return err
}

How do I handle errors in my component?

Option 1: Return the error (blocks the upstream)

go
return fmt.Errorf("processing failed: %w", err)

Option 2: Send to error port (continues flow)

go
output(ctx, "error", ErrorOutput{Error: err.Error()})
return nil

Kubernetes Integration

Why isn't my TinyNode being processed?

Check:

  1. Module is deployed and running
  2. TinyModule CR exists for the module
  3. Namespace matches
  4. No errors in controller logs
  5. Component name matches

How do I expose an HTTP endpoint?

Use the resource manager via _client port:

go
c.resourceManager.ExposePort(ctx, resource.ExposePortRequest{
    Port:      8080,
    Hostnames: []string{"api.example.com"},
})

This creates Service and Ingress resources automatically.

How does leader election work?

Each TinyNode gets a Kubernetes Lease. The pod that acquires the lease becomes leader:

go
if utils.IsLeader(ctx) {
    // Leader-only operations
}

Leaders handle write operations; readers handle read-only tasks.

Can multiple pods handle the same TinyNode?

Yes, with the leader-reader pattern:

  • One leader handles state changes
  • Multiple readers can process read-only requests
  • State propagates via TinyNode metadata

Expressions

Why isn't my expression working?

Common issues:

  1. Missing $ for root reference: &#123;&#123;$.field&#125;&#125; not &#123;&#123;field&#125;&#125;
  2. Wrong quotes: Use single quotes inside expressions: &#123;&#123;'text'&#125;&#125;
  3. Missing closing braces: &#123;&#123;$.field&#125;&#125;
  4. Type mismatch: Ensure numeric operations on numbers

How do I provide a default value?

Use the OR operator:

yaml
name: "{{$.user.name || 'Anonymous'}}"
count: "{{$.count || 0}}"

Can I use complex logic in expressions?

Expressions support:

  • Path access: &#123;&#123;$.deep.nested.value&#125;&#125;
  • Operators: &#123;&#123;$.a + $.b&#125;&#125;
  • Conditionals: &#123;&#123;$.active ? 'yes' : 'no'&#125;&#125;
  • Functions: &#123;&#123;upper($.name)&#125;&#125;

For complex logic, use a Modify component instead.

How do I access array elements?

yaml
first: "{{$.items[0]}}"
last: "{{$.items[-1]}}"
dynamic: "{{$.items[$.index]}}"

Scaling

How do I scale my flow?

  1. Module pods: Scale the Deployment
  2. Kubernetes resources: Adjust resource requests/limits
  3. Leader-reader: Implement the pattern for read-heavy workloads
  4. Parallel processing: Use iterator/aggregator patterns

Why isn't scaling improving performance?

Consider:

  • Is the bottleneck CPU/memory or I/O?
  • Are you using leader-only operations?
  • Is there contention on shared resources?
  • Does the flow support parallelization?

How do I share state across pods?

Use TinyNode metadata via _reconcile port:

go
// Leader writes
output(ctx, v1alpha1.ReconcilePort, func(n *v1alpha1.TinyNode) {
    n.Status.Metadata["key"] = "value"
})

// All pods read
value := node.Status.Metadata["key"]

Deployment

How do I deploy my module?

  1. Build Docker image
  2. Push to registry
  3. Create Helm chart
  4. Deploy with Helm

See Building Modules.

What Kubernetes version is required?

TinySystems requires Kubernetes 1.20+ for:

  • Custom Resource support
  • Server-side apply
  • Lease-based leader election

Can I run TinySystems locally?

Yes, using:

  • Minikube
  • Kind (Kubernetes in Docker)
  • k3d
  • Docker Desktop Kubernetes

Troubleshooting

Component not receiving messages

  1. Check edges are correctly configured
  2. Verify port names match exactly
  3. Check source/target node names
  4. Look for errors in controller logs

Messages being lost

  1. Are you using non-blocking output without error handling?
  2. Check for panics in component code
  3. Verify the downstream component is healthy
  4. Check resource limits (memory, CPU)

Slow performance

  1. Profile your component code
  2. Check for N+1 patterns in database queries
  3. Review blocking operations
  4. Consider caching frequently accessed data

Pod keeps restarting

  1. Check memory limits (OOM kills)
  2. Look for panics in logs
  3. Verify environment variables are set
  4. Check liveness/readiness probes

Best Practices

How should I structure my module?

my-module/
├── cmd/
│   └── main.go
├── components/
│   ├── component1/
│   │   └── component.go
│   └── component2/
│       └── component.go
├── chart/
│   └── my-module/
├── go.mod
└── Dockerfile

When should I create a new component vs. use expressions?

Use expressions for:

  • Simple data mapping
  • Field renaming
  • Basic transformations

Create a component for:

  • Complex business logic
  • External API calls
  • State management
  • Custom protocols

How do I handle secrets?

  1. Store in Kubernetes Secrets
  2. Reference via configRef in settings
  3. Never log secret values
  4. Use RBAC to restrict access
yaml
apiKey:
  configRef:
    name: my-secret
    key: api-key

Getting Help

Where can I get support?

  • Documentation: This site
  • GitHub Issues: Report bugs and feature requests
  • Community: Join discussions

How do I report a bug?

  1. Check existing issues
  2. Create a minimal reproduction
  3. Include:
    • TinySystems version
    • Kubernetes version
    • Component code (if applicable)
    • Error messages and logs
    • Steps to reproduce

Build flow-based applications on Kubernetes