mirror of
https://github.com/prdlk/dotfiles.git
synced 2026-11-08 12:57:46 +00:00
shell: fish functions -> ~/.local/bin executables + bash/zsh ports; manage ~/.agents
- 16 cross-shell utilities converted to sh/bash chezmoi executables: ai c2p cp-appid extract_agents fab gdc gh-sonr-org-migrate ghg-clone ghn gho git-summary launch_omp_livediff_overlay lc-elir mdcp mdp pj (ghg-clone not named ghg: unrelated cargo binary owns that name) - cwd/history helpers stay per-shell: yy c cd clip-last + ghg/ghn/gho cd-wrappers in bash/functions/ and zsh/functions/, loaded by rc files - fish keeps only shell-state functions; converted ones now hit PATH - cp-appid ignore gating moved to .local/bin path - dot_agents/skills: 82 skills materialized from dotstate storage so dot_claude skill symlinks resolve on fresh bootstrap; dotstate profile/symlinks.json released .agents/skills .bashrc .zshrc
This commit is contained in:
1 parent
6776366ce6
commit
6406208b35
637 files changed
+100297
-497
No files matched your search
@@ -0,0 +1,329 @@
|
||||
# Concurrency Patterns
|
||||
|
||||
## Goroutine Lifecycle Management
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Worker pool with bounded concurrency
|
||||
type WorkerPool struct {
|
||||
workers int
|
||||
tasks chan func()
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
func NewWorkerPool(workers int) *WorkerPool {
|
||||
wp := &WorkerPool{
|
||||
workers: workers,
|
||||
tasks: make(chan func(), workers*2), // Buffered channel
|
||||
}
|
||||
wp.start()
|
||||
return wp
|
||||
}
|
||||
|
||||
func (wp *WorkerPool) start() {
|
||||
for i := 0; i < wp.workers; i++ {
|
||||
wp.wg.Add(1)
|
||||
go func() {
|
||||
defer wp.wg.Done()
|
||||
for task := range wp.tasks {
|
||||
task()
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func (wp *WorkerPool) Submit(task func()) {
|
||||
wp.tasks <- task
|
||||
}
|
||||
|
||||
func (wp *WorkerPool) Shutdown() {
|
||||
close(wp.tasks)
|
||||
wp.wg.Wait()
|
||||
}
|
||||
```
|
||||
|
||||
## Channel Patterns
|
||||
|
||||
```go
|
||||
// Generator pattern
|
||||
func generateNumbers(ctx context.Context, max int) <-chan int {
|
||||
out := make(chan int)
|
||||
go func() {
|
||||
defer close(out)
|
||||
for i := 0; i < max; i++ {
|
||||
select {
|
||||
case out <- i:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
return out
|
||||
}
|
||||
|
||||
// Fan-out, fan-in pattern
|
||||
func fanOut(ctx context.Context, input <-chan int, workers int) []<-chan int {
|
||||
channels := make([]<-chan int, workers)
|
||||
for i := 0; i < workers; i++ {
|
||||
channels[i] = process(ctx, input)
|
||||
}
|
||||
return channels
|
||||
}
|
||||
|
||||
func process(ctx context.Context, input <-chan int) <-chan int {
|
||||
out := make(chan int)
|
||||
go func() {
|
||||
defer close(out)
|
||||
for val := range input {
|
||||
select {
|
||||
case out <- val * 2:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
return out
|
||||
}
|
||||
|
||||
func fanIn(ctx context.Context, channels ...<-chan int) <-chan int {
|
||||
out := make(chan int)
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for _, ch := range channels {
|
||||
wg.Add(1)
|
||||
go func(c <-chan int) {
|
||||
defer wg.Done()
|
||||
for val := range c {
|
||||
select {
|
||||
case out <- val:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}(ch)
|
||||
}
|
||||
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(out)
|
||||
}()
|
||||
|
||||
return out
|
||||
}
|
||||
```
|
||||
|
||||
## Select Statement Patterns
|
||||
|
||||
```go
|
||||
// Timeout pattern
|
||||
func fetchWithTimeout(ctx context.Context, url string) (string, error) {
|
||||
result := make(chan string, 1)
|
||||
errCh := make(chan error, 1)
|
||||
|
||||
go func() {
|
||||
// Simulate network call
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
result <- "data from " + url
|
||||
}()
|
||||
|
||||
select {
|
||||
case res := <-result:
|
||||
return res, nil
|
||||
case err := <-errCh:
|
||||
return "", err
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
return "", fmt.Errorf("timeout")
|
||||
case <-ctx.Done():
|
||||
return "", ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
// Done channel pattern for graceful shutdown
|
||||
type Server struct {
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
func (s *Server) Shutdown() {
|
||||
close(s.done)
|
||||
}
|
||||
|
||||
func (s *Server) Run(ctx context.Context) {
|
||||
ticker := time.NewTicker(1 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
fmt.Println("tick")
|
||||
case <-s.done:
|
||||
fmt.Println("shutting down")
|
||||
return
|
||||
case <-ctx.Done():
|
||||
fmt.Println("context cancelled")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Sync Primitives
|
||||
|
||||
```go
|
||||
import "sync"
|
||||
|
||||
// Mutex for protecting shared state
|
||||
type Counter struct {
|
||||
mu sync.Mutex
|
||||
count int
|
||||
}
|
||||
|
||||
func (c *Counter) Increment() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
c.count++
|
||||
}
|
||||
|
||||
func (c *Counter) Value() int {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
return c.count
|
||||
}
|
||||
|
||||
// RWMutex for read-heavy workloads
|
||||
type Cache struct {
|
||||
mu sync.RWMutex
|
||||
items map[string]string
|
||||
}
|
||||
|
||||
func (c *Cache) Get(key string) (string, bool) {
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
val, ok := c.items[key]
|
||||
return val, ok
|
||||
}
|
||||
|
||||
func (c *Cache) Set(key, value string) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
c.items[key] = value
|
||||
}
|
||||
|
||||
// sync.Once for initialization
|
||||
type Service struct {
|
||||
once sync.Once
|
||||
config *Config
|
||||
}
|
||||
|
||||
func (s *Service) getConfig() *Config {
|
||||
s.once.Do(func() {
|
||||
s.config = loadConfig() // Only called once
|
||||
})
|
||||
return s.config
|
||||
}
|
||||
```
|
||||
|
||||
## Rate Limiting and Backpressure
|
||||
|
||||
```go
|
||||
import "golang.org/x/time/rate"
|
||||
|
||||
// Token bucket rate limiter
|
||||
type RateLimiter struct {
|
||||
limiter *rate.Limiter
|
||||
}
|
||||
|
||||
func NewRateLimiter(rps int) *RateLimiter {
|
||||
return &RateLimiter{
|
||||
limiter: rate.NewLimiter(rate.Limit(rps), rps),
|
||||
}
|
||||
}
|
||||
|
||||
func (rl *RateLimiter) Process(ctx context.Context, item string) error {
|
||||
if err := rl.limiter.Wait(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
// Process item
|
||||
return nil
|
||||
}
|
||||
|
||||
// Semaphore pattern for limiting concurrency
|
||||
type Semaphore struct {
|
||||
slots chan struct{}
|
||||
}
|
||||
|
||||
func NewSemaphore(n int) *Semaphore {
|
||||
return &Semaphore{
|
||||
slots: make(chan struct{}, n),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Semaphore) Acquire() {
|
||||
s.slots <- struct{}{}
|
||||
}
|
||||
|
||||
func (s *Semaphore) Release() {
|
||||
<-s.slots
|
||||
}
|
||||
|
||||
func (s *Semaphore) Do(fn func()) {
|
||||
s.Acquire()
|
||||
defer s.Release()
|
||||
fn()
|
||||
}
|
||||
```
|
||||
|
||||
## Pipeline Pattern
|
||||
|
||||
```go
|
||||
// Stage-based processing pipeline
|
||||
func pipeline(ctx context.Context, input <-chan int) <-chan int {
|
||||
// Stage 1: Square numbers
|
||||
stage1 := make(chan int)
|
||||
go func() {
|
||||
defer close(stage1)
|
||||
for num := range input {
|
||||
select {
|
||||
case stage1 <- num * num:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Stage 2: Filter even numbers
|
||||
stage2 := make(chan int)
|
||||
go func() {
|
||||
defer close(stage2)
|
||||
for num := range stage1 {
|
||||
if num%2 == 0 {
|
||||
select {
|
||||
case stage2 <- num:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return stage2
|
||||
}
|
||||
```
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Pattern | Use Case | Key Points |
|
||||
|---------|----------|------------|
|
||||
| Worker Pool | Bounded concurrency | Limit goroutines, reuse workers |
|
||||
| Fan-out/Fan-in | Parallel processing | Distribute work, merge results |
|
||||
| Pipeline | Stream processing | Chain transformations |
|
||||
| Rate Limiter | API throttling | Control request rate |
|
||||
| Semaphore | Resource limits | Cap concurrent operations |
|
||||
| Done Channel | Graceful shutdown | Signal completion |
|
||||
Reference in new issue
Block a user