agentscope-ai / agentscope-ai/agentscope-java

[Bug]: HttpSelfRegistration.close() skips deregistration when a heartbeat re-register cycle is in flight (flaky HttpSelfRegistrationTest on CI)

Open
#3,132 1 comment 0 reactions 0 assignees View on GitHub
area/extensions bug
Dominant language
Java
Stars
5.6k
Forks
1.4k
Avg merge
3d 23h
Merged PRs (30d)
77

Description

## Description

While CI-testing PR #3131 on `windows-latest`, `HttpSelfRegistrationTest.
registrationUsesTenantAndDurableIdentityForHeartbeatAndDelete` failed
intermittently with the `deleted` latch timing out at
`HttpSelfRegistrationTest.java:106`:

```
org.opentest4j.AssertionFailedError: expected: but was:
at io.agentscope.extensions.aistio.transport.HttpSelfRegistrationTest
.registrationUsesTenantAndDurableIdentityForHeartbeatAndDelete(...:106)
```

The runner stderr showed `aistio: registered runtime-instance-key ...` **twice**,
indicating a heartbeat-failure re-register cycle ran concurrently with
`close()`.

## Root cause

`HttpSelfRegistration.close()` gates the control-plane DELETE on
`registered.get()`:

```java
if (!registered.get()) {
return; // skips the DELETE even if registeredInstanceId is still set
}
```

`heartbeatSafe()` clears `registered` **before** re-registering after a
heartbeat failure. If `close()` runs inside that window (likely on loaded
runners where a heartbeat request can fail), the DELETE is silently skipped:
the instance is leaked on the control plane, and the test's `deleted` latch
times out. Fast local machines rarely hit the window, which is why the test
is green locally and only flakes on CI.

## Impact

- Real resource leak: an instance that was registered stays registered on the
control plane after `close()` (ghost instance).
- Flaky CI: `HttpSelfRegistrationTest` fails under load.

## Suggested fix

Make `close()` best-effort unregister whenever an identity exists
(`registeredInstanceId != null`), keeping never-registered calls as a no-op
and repeat closes idempotent; widen the test latches from 2s to 10s so slow
runners don't turn slow (not stuck) callbacks into failures.

Fix will be attached to PR #3131 (discovered by its CI run).

Contributor guide

Open the contributing guide

Research direction

Start with HttpSelfRegistration.close() and heartbeatSafe(), then inspect HttpSelfRegistrationTest.registrationUsesTenantAndDurableIdentityForHeartbeatAndDelete(), which reports the failure at line 106. Run that test under the relevant CI conditions and trace the heartbeat re-registration window. Done means never-registered closes remain no-ops, repeat closes are idempotent, an existing registeredInstanceId is deleted, and the test tolerates slow callbacks with the requested latch timeout.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, backend, testing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.