Skip to content

feat(stackresource): report the last port-dial result on status - #57

Merged
ashishmax31 merged 1 commit into
mainfrom
feat/portcheck-status-result
Aug 2, 2026
Merged

feat(stackresource): report the last port-dial result on status#57
ashishmax31 merged 1 commit into
mainfrom
feat/portcheck-status-result

Conversation

@ashishmax31

Copy link
Copy Markdown
Contributor

What

PortCheck used to exist only while a declared port was failing — written on the first refusal seen while serving, deleted once every port verified open. The hub had nothing to build a release event from, and no way to tell "ports verified" from "never checked".

It now reports what the last dial said, on both the serving and the not-serving path:

field meaning
status Success or Failure — the result of the last dial
failingPortNumbers the declared ports that refused it
failingSince when the grace window opened, set only while one is open

A port that is slow to bind reports Failure and then Success once it comes up. That is intended: it tells the user the ports were actually scanned, and the follow-up corrects it. The workload is still only condemned when a Failure outlives the grace window — that behaviour and the 3 minute default are unchanged.

How

failingSince keeps its old job as the operator's countdown, and only verifyServingPorts sets it. It is read through one helper:

func graceWindowStart(pc *v1alpha1.PortCheckStatus, revision string) *metav1.Time {
	if pc == nil || pc.Revision != revision {
		return nil
	}
	return pc.FailingSince
}

A Success record has no timestamp, so a port that goes bad after verifying open opens a fresh window instead of reading through a nil pointer.

capturePortDiagnosisForNotServingWorkload (renamed from capturePortDiagnosis, so the precondition is in the name) reports the dial but never opens the window. A pod that has not started listening yet must not burn it, or the serving path would condemn on its first refusal. Writing the same record on every pass also keeps StatusHash stable, so a not-serving workload no longer looks like it is changing on every reconcile.

Tests

Two new specs in readiness_failure_test.go:

  • opens a fresh window when a verified-open port goes bad on the same revision — the nil-pointer path.
  • reports the dial without opening the grace window, and writes the same record every pass — asserts failingSince stays nil and StatusHash() does not move across three passes.

Existing specs updated for the pointer field and for Success now writing a record instead of clearing it.

make test green.

Follow-up

Hub side: show Failure as in-progress while the resource is still Pending, and as a failed release once it is Failed/Stalled. Related to the open thread on mapping Phase=Failed + Available=True.

PortCheck used to exist only while a declared port was failing: it was
written on the first refusal seen while serving and deleted once every
port verified open. The hub had nothing to build a release event from,
and no way to tell "ports verified" from "never checked".

It now reports what the last dial said, on both the serving and the
not-serving path:

  status              Success or Failure
  failingPortNumbers  the ports that refused the last dial
  failingSince        when the grace window opened, if one is open

A port that is slow to bind reports Failure and then Success once it
comes up. That is intended — it tells the user the ports were actually
scanned. The workload is still only condemned when a Failure outlives
the grace window, which is unchanged.

failingSince keeps its old job as the operator's countdown, and only
verifyServingPorts sets it. Reading it through graceWindowStart means a
Success record (no timestamp) opens a fresh window on the next failure
instead of dereferencing a nil pointer.

capturePortDiagnosisForNotServingWorkload reports the dial but never
opens the window: a pod that has not started listening yet must not burn
it, or the serving path would condemn on its first refusal. Writing the
same record every pass also keeps StatusHash stable, so a not-serving
workload no longer looks like it is changing on every reconcile.
@ashishmax31
ashishmax31 merged commit 9fb10c5 into main Aug 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant