Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Bolt's Journal

## 2026-03-09 - Lock-Free Pre-Allocated Map-Reduce for Multi-Regional Queries
**Learning:** Performing multi-regional queries (like `listAllRegions` across 24 GCP regions) concurrently using a shared slice protected by `sync.Mutex` causes lock contention, slice allocation churn, and heavy garbage collection overhead. Utilizing a lock-free, pre-allocated map-reduce pattern using a slice of slices (`[][]T`) eliminates mutex contention entirely, and pre-allocating the final result slice based on the exact sum of sizes of individual regional results reduces heap allocations considerably.
**Action:** Always favor lock-free, index-mapped pre-allocation arrays (`[][]T`) over shared mutex-protected slices (`[]T`) when collecting results concurrently from a known, fixed number of concurrent tasks.

## 2026-03-08 - GCP Logging Client Caching & Connection Longevity
**Learning:** Establishing the GCP Stackdriver Logging client requires repeated Google credential discovery and connection establishment, causing high latency (~300ms) inside a reactive TUI interface. Caching `logadmin.Client` instances via a project-aware map with thread-safe `sync.Mutex` ensures subsequent streaming and log extraction operations are instantaneous. Crucially, calling `Close()` on individual stream terminations must be a no-op to prevent premature teardown of connection pools shared across other active streaming views.
**Action:** Keep GCP Logging clients cached globally by project and handle connection termination via a no-op `Close` method, while adding test-isolation resets in unit tests.
Expand Down
34 changes: 22 additions & 12 deletions internal/run/api/domainmapping/domainmapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,35 @@ func List(project, region string) ([]model.DomainMapping, error) {
}

func listAllRegions(project string) ([]model.DomainMapping, error) {
var (
mu sync.Mutex
domainMappings []model.DomainMapping
wg sync.WaitGroup
)

for _, region := range api_region.List() {
// Optimization: lock-free, pre-allocated map-reduce pattern with a slice of slices [][]model.DomainMapping.
// This eliminates mutex contention across concurrent region requests, avoids repeated slice resizing/heap allocations,
// and optimizes concurrency to reduce latency and memory usage.
regions := api_region.List()
results := make([][]model.DomainMapping, len(regions))
var wg sync.WaitGroup

for i, region := range regions {
wg.Add(1)
go func(r string) {
go func(idx int, r string) {
defer wg.Done()
if dms, err := List(project, r); err == nil {
mu.Lock()
domainMappings = append(domainMappings, dms...)
mu.Unlock()
results[idx] = dms
}
}(region)
}(i, region)
}

wg.Wait()

total := 0
for _, dms := range results {
total += len(dms)
}

domainMappings := make([]model.DomainMapping, 0, total)
for _, dms := range results {
domainMappings = append(domainMappings, dms...)
}

return domainMappings, nil
}

Expand Down
34 changes: 22 additions & 12 deletions internal/run/api/job/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,27 +79,37 @@ func mapJob(resp *runpb.Job, region string) model.Job {
}

func listAllRegions(project string) ([]model.Job, error) {
var (
mu sync.Mutex
jobs []model.Job
wg sync.WaitGroup
)

for _, region := range api_region.List() {
// Optimization: lock-free, pre-allocated map-reduce pattern with a slice of slices [][]model.Job.
// This eliminates mutex contention across concurrent region requests, avoids repeated slice resizing/heap allocations,
// and optimizes concurrency to reduce latency and memory usage.
regions := api_region.List()
results := make([][]model.Job, len(regions))
var wg sync.WaitGroup

for i, region := range regions {
wg.Add(1)
go func(r string) {
go func(idx int, r string) {
defer wg.Done()
// Call List recursively for each region
// We ignore errors here to allow partial success (e.g. if one region is down or disabled)
if j, err := List(project, r); err == nil {
mu.Lock()
jobs = append(jobs, j...)
mu.Unlock()
results[idx] = j
}
}(region)
}(i, region)
}

wg.Wait()

total := 0
for _, j := range results {
total += len(j)
}

jobs := make([]model.Job, 0, total)
for _, j := range results {
jobs = append(jobs, j...)
}

return jobs, nil
}

Expand Down
34 changes: 22 additions & 12 deletions internal/run/api/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,26 +299,36 @@ func UpdateTraffic(ctx context.Context, project, region, serviceName string, tar
}

func listAllRegions(project string) ([]model.Service, error) {
var (
mu sync.Mutex
services []model.Service
wg sync.WaitGroup
)

for _, region := range api_region.List() {
// Optimization: lock-free, pre-allocated map-reduce pattern with a slice of slices [][]model.Service.
// This eliminates mutex contention across concurrent region requests, avoids repeated slice resizing/heap allocations,
// and optimizes concurrency to reduce latency and memory usage.
regions := api_region.List()
results := make([][]model.Service, len(regions))
var wg sync.WaitGroup

for i, region := range regions {
wg.Add(1)
go func(r string) {
go func(idx int, r string) {
defer wg.Done()
// Call List recursively for each region
// We ignore errors here to allow partial success (e.g. if one region is down or disabled)
if s, err := List(project, r); err == nil {
mu.Lock()
services = append(services, s...)
mu.Unlock()
results[idx] = s
}
}(region)
}(i, region)
}

wg.Wait()

total := 0
for _, s := range results {
total += len(s)
}

services := make([]model.Service, 0, total)
for _, s := range results {
services = append(services, s...)
}

return services, nil
}
21 changes: 20 additions & 1 deletion internal/run/api/service/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -642,4 +642,23 @@ func TestUpdateAuthentication_Error(t *testing.T) {
assert.Error(t, err)
assert.Contains(t, err.Error(), "failed to update service")
}


func BenchmarkListAllRegions(b *testing.B) {
originalClient := apiClient
defer func() { apiClient = originalClient }()

mock := &MockClient{}
apiClient = mock

mock.ListServicesFunc = func(ctx context.Context, project, region string) ([]*runpb.Service, error) {
return []*runpb.Service{
{Name: "projects/" + project + "/locations/" + region + "/services/s1"},
{Name: "projects/" + project + "/locations/" + region + "/services/s2"},
}, nil
}

b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = List("my-project", api_region.ALL)
}
}
34 changes: 22 additions & 12 deletions internal/run/api/workerpool/workerpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,27 +111,37 @@ func UpdateScaling(ctx context.Context, project, region, workerPoolName string,
}

func listAllRegions(project string) ([]model.WorkerPool, error) {
var (
mu sync.Mutex
workerPools []model.WorkerPool
wg sync.WaitGroup
)

for _, region := range api_region.List() {
// Optimization: lock-free, pre-allocated map-reduce pattern with a slice of slices [][]model.WorkerPool.
// This eliminates mutex contention across concurrent region requests, avoids repeated slice resizing/heap allocations,
// and optimizes concurrency to reduce latency and memory usage.
regions := api_region.List()
results := make([][]model.WorkerPool, len(regions))
var wg sync.WaitGroup

for i, region := range regions {
wg.Add(1)
go func(r string) {
go func(idx int, r string) {
defer wg.Done()
// Call List recursively for each region
// We ignore errors here to allow partial success (e.g. if one region is down or disabled)
if wp, err := List(project, r); err == nil {
mu.Lock()
workerPools = append(workerPools, wp...)
mu.Unlock()
results[idx] = wp
}
}(region)
}(i, region)
}

wg.Wait()

total := 0
for _, wp := range results {
total += len(wp)
}

workerPools := make([]model.WorkerPool, 0, total)
for _, wp := range results {
workerPools = append(workerPools, wp...)
}

return workerPools, nil
}

Loading