Fix race conditions and improve lifecycle safety (#150) #152

Merged
bagas merged 1 commits from staging into main 2026-07-17 13:21:32 +07:00
Owner

Summary

Comprehensive fixes for race conditions, concurrency bugs, and code quality improvements in the lifecycle module and related test files.

Changes

Race Condition Fixes

  • Fixed data race in SetChannel() and Channel() by adding mutex protection
  • Fixed data race in StartedAt() by adding mutex protection
  • Fixed test race conditions in transport and interaction packages where variables were shared between goroutines

Concurrency Safety Improvements

  • Refactored Close() to release mutex before calling external code, preventing potential deadlocks
  • Made SetChannel() reject calls after Close() to prevent setting channel on torn-down lifecycle
  • Made SetStatus() ignore calls after Close() to ensure CLOSED is a terminal state
  • Added nil check to SetChannel() to prevent masking upstream bugs

Code Quality Improvements

  • Refactored Close() to extract helper methods: closeChannel(), closeConnection(), cleanupRegistry(), cleanupForwarder()
  • Fixed isClosedError() to remove redundant string comparison
  • Added PortRegistry interface for better interface segregation (removed dependency on full port.Port)
  • Made cleanupRegistry() conditional on non-empty slug to avoid unnecessary registry calls
  • Fixed startedAt to be set when session starts running instead of at object creation

Reviewed-on: #150
Co-authored-by: Bagas bagas@fossy.my.id
Co-committed-by: Bagas bagas@fossy.my.id

## Summary Comprehensive fixes for race conditions, concurrency bugs, and code quality improvements in the lifecycle module and related test files. ## Changes ### Race Condition Fixes - Fixed data race in `SetChannel()` and `Channel()` by adding mutex protection - Fixed data race in `StartedAt()` by adding mutex protection - Fixed test race conditions in `transport` and `interaction` packages where variables were shared between goroutines ### Concurrency Safety Improvements - Refactored `Close()` to release mutex before calling external code, preventing potential deadlocks - Made `SetChannel()` reject calls after `Close()` to prevent setting channel on torn-down lifecycle - Made `SetStatus()` ignore calls after `Close()` to ensure CLOSED is a terminal state - Added nil check to `SetChannel()` to prevent masking upstream bugs ### Code Quality Improvements - Refactored `Close()` to extract helper methods: `closeChannel()`, `closeConnection()`, `cleanupRegistry()`, `cleanupForwarder()` - Fixed `isClosedError()` to remove redundant string comparison - Added `PortRegistry` interface for better interface segregation (removed dependency on full `port.Port`) - Made `cleanupRegistry()` conditional on non-empty slug to avoid unnecessary registry calls - Fixed `startedAt` to be set when session starts running instead of at object creation Reviewed-on: https://git.fossy.my.id/bagas/tunnel-please/pulls/150 Co-authored-by: Bagas <bagas@fossy.my.id> Co-committed-by: Bagas <bagas@fossy.my.id>
bagas added 1 commit 2026-07-17 13:18:47 +07:00
Fix race conditions and improve lifecycle safety (#150)
SonarQube Scan / SonarQube Trigger (push) Successful in 4m1s
Docker Build and Push / Run Tests (push) Successful in 2m28s
Docker Build and Push / Build and Push Docker Image (push) Successful in 18m27s
Tests / Run Tests (pull_request) Successful in 2m29s
e8be839dac
## Summary
Comprehensive fixes for race conditions, concurrency bugs, and code quality improvements in the lifecycle module and related test files.

## Changes

### Race Condition Fixes
- Fixed data race in `SetChannel()` and `Channel()` by adding mutex protection
- Fixed data race in `StartedAt()` by adding mutex protection
- Fixed test race conditions in `transport` and `interaction` packages where variables were shared between goroutines

### Concurrency Safety Improvements
- Refactored `Close()` to release mutex before calling external code, preventing potential deadlocks
- Made `SetChannel()` reject calls after `Close()` to prevent setting channel on torn-down lifecycle
- Made `SetStatus()` ignore calls after `Close()` to ensure CLOSED is a terminal state
- Added nil check to `SetChannel()` to prevent masking upstream bugs

### Code Quality Improvements
- Refactored `Close()` to extract helper methods: `closeChannel()`, `closeConnection()`, `cleanupRegistry()`, `cleanupForwarder()`
- Fixed `isClosedError()` to remove redundant string comparison
- Added `PortRegistry` interface for better interface segregation (removed dependency on full `port.Port`)
- Made `cleanupRegistry()` conditional on non-empty slug to avoid unnecessary registry calls
- Fixed `startedAt` to be set when session starts running instead of at object creation

Reviewed-on: #150
Co-authored-by: Bagas <bagas@fossy.my.id>
Co-committed-by: Bagas <bagas@fossy.my.id>
bagas merged commit fabfd96600 into main 2026-07-17 13:21:32 +07:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bagas/tunnel-please#152