2
0

Compare commits

...

2 Commits

Author SHA1 Message Date
f33d0a54c4 refactor(client): simplify HTTP client and reporter daemon implementation
Some checks failed
CI / build-and-test (push) Has been cancelled
Release / build (amd64, darwin) (push) Successful in 57s
Release / build (amd64, linux) (push) Successful in 1m4s
Release / build (amd64, windows) (push) Successful in 1m13s
Release / build (arm64, linux) (push) Successful in 53s
Release / build (arm64, darwin) (push) Successful in 1m16s
Release / release (push) Successful in 24s
Use http.DefaultClient when TLS verification is not skipped, removing unnecessary custom transport configuration. Replace select-based daemon loop with time.AfterFunc for cleaner implementation and remove verbose error logging in RunDaemon.
2026-01-25 14:31:47 -05:00
899ca015b1 fix(poll): revert context inheritance to prevent deadlock
All checks were successful
CI / build-and-test (push) Successful in 1m0s
Release / build (amd64, linux) (push) Successful in 1m8s
Release / build (amd64, darwin) (push) Successful in 1m25s
Release / build (amd64, windows) (push) Successful in 51s
Release / build (arm64, darwin) (push) Successful in 1m0s
Release / build (arm64, linux) (push) Successful in 1m9s
Release / release (push) Successful in 26s
The v1.0.3 change that made poller contexts inherit from the parent
context caused a deadlock where runners would start but never poll
for tasks.

Reverted to using context.Background() for pollingCtx and jobsCtx.
Graceful shutdown still works via explicit Shutdown() call which
cancels the polling context.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 13:51:47 -05:00
4 changed files with 16 additions and 35 deletions

View File

@@ -218,7 +218,7 @@ func runDaemon(ctx context.Context, daemArgs *daemonArgs, configFile *string) fu
}
}()
poller := poll.New(ctx, cfg, cli, runner)
poller := poll.New(cfg, cli, runner)
poller.SetBandwidthManager(bandwidthManager)
if daemArgs.Once || reg.Ephemeral {

View File

@@ -40,11 +40,11 @@ type Poller struct {
done chan struct{}
}
// New creates a new Poller instance with the given context for shutdown propagation.
func New(ctx context.Context, cfg *config.Config, client client.Client, runner *run.Runner) *Poller {
// Inherit from parent context so shutdown signals propagate properly
pollingCtx, shutdownPolling := context.WithCancel(ctx)
jobsCtx, shutdownJobs := context.WithCancel(ctx)
// New creates a new Poller instance.
func New(cfg *config.Config, client client.Client, runner *run.Runner) *Poller {
// Use independent contexts - shutdown is handled explicitly via Shutdown()
pollingCtx, shutdownPolling := context.WithCancel(context.Background())
jobsCtx, shutdownJobs := context.WithCancel(context.Background())
done := make(chan struct{})

View File

@@ -8,7 +8,6 @@ import (
"crypto/tls"
"net/http"
"strings"
"time"
"code.gitea.io/actions-proto-go/ping/v1/pingv1connect"
"code.gitea.io/actions-proto-go/runner/v1/runnerv1connect"
@@ -16,24 +15,16 @@ import (
)
func getHTTPClient(endpoint string, insecure bool) *http.Client {
transport := &http.Transport{
MaxIdleConns: 10,
MaxIdleConnsPerHost: 5,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
DisableKeepAlives: false,
}
if strings.HasPrefix(endpoint, "https://") && insecure {
transport.TLSClientConfig = &tls.Config{
InsecureSkipVerify: true,
return &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
}
return &http.Client{
Transport: transport,
Timeout: 30 * time.Second,
}
return http.DefaultClient
}
// New returns a new runner client.

View File

@@ -190,20 +190,10 @@ func (r *Reporter) RunDaemon() {
return
}
if err := r.ReportLog(false); err != nil {
log.WithError(err).Warn("failed to report log")
}
if err := r.ReportState(); err != nil {
log.WithError(err).Warn("failed to report state")
}
_ = r.ReportLog(false)
_ = r.ReportState()
// Use select with context to allow clean shutdown
select {
case <-r.ctx.Done():
return
case <-time.After(time.Second):
r.RunDaemon()
}
time.AfterFunc(time.Second, r.RunDaemon)
}
// Logf adds a formatted log message to the report.