Contributing to Olla¶
Thank you for considering contributing to Olla! This guide will help you get started.
Code of Conduct¶
Be respectful and constructive. We're all here to build something great together.
Getting Started¶
1. Fork and Clone¶
# Fork on GitHub, then:
git clone https://github.com/YOUR_USERNAME/olla.git
cd olla
git remote add upstream https://github.com/thushan/olla.git
2. Create a Branch¶
# Update main branch
git checkout main
git pull upstream main
# Create feature branch
git checkout -b feature/your-feature-name
3. Make Changes¶
Follow the coding standards and ensure tests pass:
4. Commit¶
Write clear commit messages:
git add .
git commit -m "feat: add support for new endpoint type
- Implement profile for X provider
- Add converter for X API format
- Include tests and documentation"
Commit Message Format¶
Follow conventional commits:
Types: - feat
: New feature - fix
: Bug fix - docs
: Documentation only - style
: Code style (formatting, etc) - refactor
: Code restructuring - perf
: Performance improvement - test
: Adding tests - chore
: Maintenance tasks
Code Standards¶
Go Style¶
Follow standard Go conventions:
// Good - exported types have comments
// Endpoint represents a backend LLM service
type Endpoint struct {
URL string
Priority int
}
// Good - error handling
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
Package Structure¶
// Good - small, focused packages
package balancer // Just load balancing logic
// Bad - kitchen sink packages
package utils // Too generic
Error Handling¶
// Define specific errors
var (
ErrEndpointNotFound = errors.New("endpoint not found")
ErrCircuitOpen = errors.New("circuit breaker open")
)
// Wrap errors with context
if err := doSomething(); err != nil {
return fmt.Errorf("failed to process: %w", err)
}
Testing¶
Every feature needs tests:
func TestEndpointSelection(t *testing.T) {
// Arrange
endpoints := []*Endpoint{
{URL: "http://a", Priority: 100},
{URL: "http://b", Priority: 50},
}
// Act
selected := selector.Select(endpoints)
// Assert
if selected.URL != "http://a" {
t.Errorf("expected highest priority, got %s", selected.URL)
}
}
Comments¶
Write comments for "why", not "what":
// Bad - states the obvious
// Increment counter
counter++
// Good - explains reasoning
// Use exponential backoff to avoid overwhelming
// the endpoint during recovery
delay := time.Second * time.Duration(math.Pow(2, float64(attempts)))
Pull Request Process¶
1. Before Submitting¶
- Tests pass:
make test
- Linting passes:
make lint
- Code formatted:
make fmt
- Documentation updated
- Benchmarks run (if performance-critical)
2. PR Description¶
Use the template:
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] Unit tests pass
- [ ] Integration tests pass
- [ ] Manual testing completed
## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Comments added for complex parts
- [ ] Documentation updated
- [ ] No new warnings
3. Review Process¶
- Automated checks run
- Maintainer review
- Address feedback
- Merge when approved
Testing Requirements¶
Unit Tests¶
Required for all new code:
Integration Tests¶
For new features:
Benchmarks¶
For performance-critical code:
Documentation¶
Code Documentation¶
// ProxyService handles request forwarding to backend endpoints.
// It implements circuit breaking, retry logic, and connection pooling.
type ProxyService interface {
// ProxyRequest forwards an HTTP request to a backend endpoint.
// Returns an error if no healthy endpoints are available.
ProxyRequest(ctx context.Context, w http.ResponseWriter, r *http.Request) error
}
User Documentation¶
Update relevant docs in docs/content/
:
- API changes:
api/reference.md
- New features: Appropriate concept guide
- Configuration:
configuration/reference.md
Adding New Features¶
New Endpoint Type¶
- Create profile in
config/profiles/
- Implement converter in
internal/adapter/converter/
- Add tests in
internal/adapter/converter/
- Update documentation
New Load Balancer¶
- Implement
EndpointSelector
interface - Add to balancer factory
- Write comprehensive tests
- Document behaviour
New Statistics¶
- Update
stats.Collector
- Use atomic operations
- Expose via status endpoint
- Add to documentation
Performance Guidelines¶
Benchmarking¶
Always benchmark performance-critical code:
func BenchmarkEndpointSelection(b *testing.B) {
endpoints := generateEndpoints(100)
selector := NewPrioritySelector()
b.ResetTimer()
for i := 0; i < b.N; i++ {
selector.Select(endpoints)
}
}
Memory Allocation¶
Minimise allocations:
// Bad - allocates on each call
func process() []byte {
return make([]byte, 1024)
}
// Good - reuses buffer
var bufferPool = sync.Pool{
New: func() interface{} {
return make([]byte, 1024)
},
}
func process() []byte {
buf := bufferPool.Get().([]byte)
defer bufferPool.Put(buf)
return buf
}
Common Contributions¶
Bug Fixes¶
- Create failing test
- Fix the bug
- Ensure test passes
- Submit PR with test
Documentation¶
- Identify gap or error
- Make correction
- Verify accuracy
- Submit PR
Performance Improvements¶
- Benchmark current performance
- Implement improvement
- Benchmark new performance
- Include results in PR
Getting Help¶
Discord¶
Join our Discord for discussions: [Coming Soon]
GitHub Issues¶
- Check existing issues first
- Use issue templates
- Provide reproduction steps
Pull Request Help¶
Tag maintainers for review: - @thushan - Project lead
Recognition¶
Contributors are recognised in: - CONTRIBUTORS.md file - Release notes - Project documentation
Legal¶
By contributing, you agree that your contributions will be licensed under the same license as the project (Apache 2.0).
Next Steps¶
- Set up your Development Environment
- Review Technical Patterns
- Check Testing Guide
- Start with a good first issue