diff --git a/src/main/java/com/volcengine/ark/runtime/models/environment/EnvConfig.java b/src/main/java/com/volcengine/ark/runtime/models/environment/EnvConfig.java index eb2560b..97c12f9 100644 --- a/src/main/java/com/volcengine/ark/runtime/models/environment/EnvConfig.java +++ b/src/main/java/com/volcengine/ark/runtime/models/environment/EnvConfig.java @@ -32,7 +32,6 @@ EnvConfig.JSON_PROPERTY_PACKAGES, EnvConfig.JSON_PROPERTY_ENV, EnvConfig.JSON_PROPERTY_SETUP_SCRIPT, - EnvConfig.JSON_PROPERTY_ACTIVE_RECOVERY, EnvConfig.JSON_PROPERTY_TOS }) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.21.0") @@ -57,10 +56,6 @@ public class EnvConfig { @javax.annotation.Nullable private String setupScript; - public static final String JSON_PROPERTY_ACTIVE_RECOVERY = "active_recovery"; - @javax.annotation.Nullable - private Boolean activeRecovery; - public static final String JSON_PROPERTY_TOS = "tos"; @javax.annotation.Nullable private TosConfig tos; @@ -201,31 +196,6 @@ public void setSetupScript(@javax.annotation.Nullable String setupScript) { this.setupScript = setupScript; } - public EnvConfig activeRecovery(@javax.annotation.Nullable Boolean activeRecovery) { - - this.activeRecovery = activeRecovery; - return this; - } - - /** - * 是否启用 Work 积极恢复;仅 self_hosted Environment 支持,省略时等同于 false。该配置 仅允许在 Environment 级设置,不允许通过 Session override/upgrade 覆盖。开启后,平台在 Work 已 stopped、仍有未闭合 agent.tool_use 且 recovery_count 少于 5 次时将 Work 重新排队, 不按 stop_reason 排除。只有 Worker 上报 completed 且全部 tool_use 已闭合后才会清零计数。 - * @return activeRecovery - */ - @javax.annotation.Nullable - @JsonProperty(value = JSON_PROPERTY_ACTIVE_RECOVERY, required = false) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - - public Boolean getActiveRecovery() { - return activeRecovery; - } - - - @JsonProperty(value = JSON_PROPERTY_ACTIVE_RECOVERY, required = false) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setActiveRecovery(@javax.annotation.Nullable Boolean activeRecovery) { - this.activeRecovery = activeRecovery; - } - public EnvConfig tos(@javax.annotation.Nullable TosConfig tos) { this.tos = tos; @@ -266,13 +236,12 @@ public boolean equals(Object o) { Objects.equals(this.packages, envConfig.packages) && Objects.equals(this.env, envConfig.env) && Objects.equals(this.setupScript, envConfig.setupScript) && - Objects.equals(this.activeRecovery, envConfig.activeRecovery) && Objects.equals(this.tos, envConfig.tos); } @Override public int hashCode() { - return Objects.hash(type, networking, packages, env, setupScript, activeRecovery, tos); + return Objects.hash(type, networking, packages, env, setupScript, tos); } @Override @@ -284,7 +253,6 @@ public String toString() { sb.append(" packages: ").append(toIndentedString(packages)).append("\n"); sb.append(" env: ").append(toIndentedString(env)).append("\n"); sb.append(" setupScript: ").append(toIndentedString(setupScript)).append("\n"); - sb.append(" activeRecovery: ").append(toIndentedString(activeRecovery)).append("\n"); sb.append(" tos: ").append(toIndentedString(tos)).append("\n"); sb.append("}"); return sb.toString(); @@ -330,10 +298,6 @@ public EnvConfig.Builder setupScript(String setupScript) { this.instance.setupScript = setupScript; return this; } - public EnvConfig.Builder activeRecovery(Boolean activeRecovery) { - this.instance.activeRecovery = activeRecovery; - return this; - } public EnvConfig.Builder tos(TosConfig tos) { this.instance.tos = tos; return this; @@ -377,7 +341,6 @@ public EnvConfig.Builder toBuilder() { .packages(getPackages()) .env(getEnv()) .setupScript(getSetupScript()) - .activeRecovery(getActiveRecovery()) .tos(getTos()); } diff --git a/src/main/java/com/volcengine/ark/runtime/models/environment/EnvironmentWorkPoll200Response.java b/src/main/java/com/volcengine/ark/runtime/models/environment/EnvironmentWorkPoll200Response.java index 390c2c2..d05c5ea 100644 --- a/src/main/java/com/volcengine/ark/runtime/models/environment/EnvironmentWorkPoll200Response.java +++ b/src/main/java/com/volcengine/ark/runtime/models/environment/EnvironmentWorkPoll200Response.java @@ -43,7 +43,6 @@ EnvironmentWorkPoll200Response.JSON_PROPERTY_STOP_REQUESTED_AT, EnvironmentWorkPoll200Response.JSON_PROPERTY_STOPPED_AT, EnvironmentWorkPoll200Response.JSON_PROPERTY_STOP_REASON, - EnvironmentWorkPoll200Response.JSON_PROPERTY_RECOVERY_COUNT, EnvironmentWorkPoll200Response.JSON_PROPERTY_TYPE }) @JsonTypeName("EnvironmentWork_poll_200_response") @@ -101,10 +100,6 @@ public class EnvironmentWorkPoll200Response { @javax.annotation.Nullable private WorkStopReason stopReason; - public static final String JSON_PROPERTY_RECOVERY_COUNT = "recovery_count"; - @javax.annotation.Nullable - private Integer recoveryCount; - /** * 对象类型,固定为 `work`。 */ @@ -460,7 +455,7 @@ public EnvironmentWorkPoll200Response stopReason(@javax.annotation.Nullable Work } /** - * 最近一次停止原因。首次停止前省略;state 为 stopping / stopped 时返回本次停止原因; 自动恢复到 queued / starting / active 后仍保留上一次停止原因,当前生命周期状态以 `state` 为准。 + * 最近一次停止原因。首次停止前省略;state 为 stopping / stopped 时返回本次停止原因。原 owner 通过 Heartbeat 将 `stopped + lease_expired` 恢复为 active 时清除此字段。 * @return stopReason */ @javax.annotation.Nullable @@ -478,31 +473,6 @@ public void setStopReason(@javax.annotation.Nullable WorkStopReason stopReason) this.stopReason = stopReason; } - public EnvironmentWorkPoll200Response recoveryCount(@javax.annotation.Nullable Integer recoveryCount) { - - this.recoveryCount = recoveryCount; - return this; - } - - /** - * 自上次成功完成且全部 tool_use 已闭合后,平台已自动将本 Work 重新排队的次数; 首次执行或字段省略时按 0 处理。手动 Ensure 不会清零该计数。 - * @return recoveryCount - */ - @javax.annotation.Nullable - @JsonProperty(value = JSON_PROPERTY_RECOVERY_COUNT, required = false) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - - public Integer getRecoveryCount() { - return recoveryCount; - } - - - @JsonProperty(value = JSON_PROPERTY_RECOVERY_COUNT, required = false) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setRecoveryCount(@javax.annotation.Nullable Integer recoveryCount) { - this.recoveryCount = recoveryCount; - } - public EnvironmentWorkPoll200Response type(@javax.annotation.Nonnull TypeEnum type) { this.type = type; @@ -551,13 +521,12 @@ public boolean equals(Object o) { Objects.equals(this.stopRequestedAt, environmentWorkPoll200Response.stopRequestedAt) && Objects.equals(this.stoppedAt, environmentWorkPoll200Response.stoppedAt) && Objects.equals(this.stopReason, environmentWorkPoll200Response.stopReason) && - Objects.equals(this.recoveryCount, environmentWorkPoll200Response.recoveryCount) && Objects.equals(this.type, environmentWorkPoll200Response.type); } @Override public int hashCode() { - return Objects.hash(id, acknowledgedAt, createdAt, data, environmentId, latestHeartbeatAt, tags, secret, startedAt, state, stopRequestedAt, stoppedAt, stopReason, recoveryCount, type); + return Objects.hash(id, acknowledgedAt, createdAt, data, environmentId, latestHeartbeatAt, tags, secret, startedAt, state, stopRequestedAt, stoppedAt, stopReason, type); } @Override @@ -577,7 +546,6 @@ public String toString() { sb.append(" stopRequestedAt: ").append(toIndentedString(stopRequestedAt)).append("\n"); sb.append(" stoppedAt: ").append(toIndentedString(stoppedAt)).append("\n"); sb.append(" stopReason: ").append(toIndentedString(stopReason)).append("\n"); - sb.append(" recoveryCount: ").append(toIndentedString(recoveryCount)).append("\n"); sb.append(" type: ").append(toIndentedString(type)).append("\n"); sb.append("}"); return sb.toString(); @@ -655,10 +623,6 @@ public EnvironmentWorkPoll200Response.Builder stopReason(WorkStopReason stopReas this.instance.stopReason = stopReason; return this; } - public EnvironmentWorkPoll200Response.Builder recoveryCount(Integer recoveryCount) { - this.instance.recoveryCount = recoveryCount; - return this; - } public EnvironmentWorkPoll200Response.Builder type(TypeEnum type) { this.instance.type = type; return this; @@ -710,7 +674,6 @@ public EnvironmentWorkPoll200Response.Builder toBuilder() { .stopRequestedAt(getStopRequestedAt()) .stoppedAt(getStoppedAt()) .stopReason(getStopReason()) - .recoveryCount(getRecoveryCount()) .type(getType()); } diff --git a/src/main/java/com/volcengine/ark/runtime/models/environment/HeartbeatRequest.java b/src/main/java/com/volcengine/ark/runtime/models/environment/HeartbeatRequest.java index f7b365e..b72c460 100644 --- a/src/main/java/com/volcengine/ark/runtime/models/environment/HeartbeatRequest.java +++ b/src/main/java/com/volcengine/ark/runtime/models/environment/HeartbeatRequest.java @@ -28,7 +28,8 @@ HeartbeatRequest.JSON_PROPERTY_ENVIRONMENT_ID, HeartbeatRequest.JSON_PROPERTY_WORK_ID, HeartbeatRequest.JSON_PROPERTY_DESIRED_TTL_SECONDS, - HeartbeatRequest.JSON_PROPERTY_EXPECTED_LAST_HEARTBEAT + HeartbeatRequest.JSON_PROPERTY_EXPECTED_LAST_HEARTBEAT, + HeartbeatRequest.JSON_PROPERTY_ARK_WORKER_I_D }) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.21.0") public class HeartbeatRequest { @@ -48,6 +49,10 @@ public class HeartbeatRequest { @javax.annotation.Nullable private String expectedLastHeartbeat; + public static final String JSON_PROPERTY_ARK_WORKER_I_D = "Ark-Worker-ID"; + @javax.annotation.Nullable + private String arkWorkerID; + public HeartbeatRequest() { } @@ -151,6 +156,28 @@ public void setExpectedLastHeartbeat(@javax.annotation.Nullable String expectedL this.expectedLastHeartbeat = expectedLastHeartbeat; } + public HeartbeatRequest arkWorkerID(@javax.annotation.Nullable String arkWorkerID) { + this.arkWorkerID = arkWorkerID; + return this; + } + + /** + * Worker identity used by Poll, Ack, and Heartbeat for ownership checks. + * @return arkWorkerID + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ARK_WORKER_I_D, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public String getArkWorkerID() { + return arkWorkerID; + } + + @JsonProperty(value = JSON_PROPERTY_ARK_WORKER_I_D, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setArkWorkerID(@javax.annotation.Nullable String arkWorkerID) { + this.arkWorkerID = arkWorkerID; + } + @Override public boolean equals(Object o) { @@ -164,12 +191,13 @@ public boolean equals(Object o) { return Objects.equals(this.environmentId, heartbeatRequest.environmentId) && Objects.equals(this.workId, heartbeatRequest.workId) && Objects.equals(this.desiredTtlSeconds, heartbeatRequest.desiredTtlSeconds) && - Objects.equals(this.expectedLastHeartbeat, heartbeatRequest.expectedLastHeartbeat); + Objects.equals(this.expectedLastHeartbeat, heartbeatRequest.expectedLastHeartbeat) && + Objects.equals(this.arkWorkerID, heartbeatRequest.arkWorkerID); } @Override public int hashCode() { - return Objects.hash(environmentId, workId, desiredTtlSeconds, expectedLastHeartbeat); + return Objects.hash(environmentId, workId, desiredTtlSeconds, expectedLastHeartbeat, arkWorkerID); } @Override @@ -180,6 +208,7 @@ public String toString() { sb.append(" workId: ").append(toIndentedString(workId)).append("\n"); sb.append(" desiredTtlSeconds: ").append(toIndentedString(desiredTtlSeconds)).append("\n"); sb.append(" expectedLastHeartbeat: ").append(toIndentedString(expectedLastHeartbeat)).append("\n"); + sb.append(" arkWorkerID: ").append(toIndentedString(arkWorkerID)).append("\n"); sb.append("}"); return sb.toString(); } @@ -220,6 +249,10 @@ public HeartbeatRequest.Builder expectedLastHeartbeat(String expectedLastHeartbe this.instance.expectedLastHeartbeat = expectedLastHeartbeat; return this; } + public HeartbeatRequest.Builder arkWorkerID(String arkWorkerID) { + this.instance.arkWorkerID = arkWorkerID; + return this; + } /** @@ -257,7 +290,8 @@ public HeartbeatRequest.Builder toBuilder() { .environmentId(getEnvironmentId()) .workId(getWorkId()) .desiredTtlSeconds(getDesiredTtlSeconds()) - .expectedLastHeartbeat(getExpectedLastHeartbeat()); + .expectedLastHeartbeat(getExpectedLastHeartbeat()) + .arkWorkerID(getArkWorkerID()); } diff --git a/src/main/java/com/volcengine/ark/runtime/models/environment/StopWorkBody.java b/src/main/java/com/volcengine/ark/runtime/models/environment/StopWorkBody.java index f2c1ebd..ab614f7 100644 --- a/src/main/java/com/volcengine/ark/runtime/models/environment/StopWorkBody.java +++ b/src/main/java/com/volcengine/ark/runtime/models/environment/StopWorkBody.java @@ -73,7 +73,7 @@ public StopWorkBody reason(@javax.annotation.Nullable WorkStopReason reason) { } /** - * 强制停止原因;仅允许与 `force=true` 一起提交,省略时按 `others` 记录。 Worker 正常完成时传 `completed`,异常退出时传 `worker_abnormal`;用户或管理员操作分别传 `user_cancelled` 或 `admin_stopped`,无法归类时传 `others`。`lease_expired` 仅由平台在租约 过期时写入,不应通过 StopWork 上报。该字段用于停止诊断,并在 Worker 上报 `completed` 且全部 tool_use 已闭合时作为清零恢复次数的信号;平台不会按停止原因排除积极恢复。 + * 强制停止原因;仅允许与 `force=true` 一起提交,省略时按 `others` 记录。 Worker 正常完成时传 `completed`,异常退出时传 `worker_abnormal`;用户或管理员操作分别传 `user_cancelled` 或 `admin_stopped`,无法归类时传 `others`。`lease_expired` 仅由平台在租约过期时写入,不应通过 StopWork 上报。该字段仅用于停止诊断;强停不会自动重新排队。 * @return reason */ @javax.annotation.Nullable diff --git a/src/main/java/com/volcengine/ark/runtime/models/environment/WorkItem.java b/src/main/java/com/volcengine/ark/runtime/models/environment/WorkItem.java index ec2da50..8ccb0d6 100644 --- a/src/main/java/com/volcengine/ark/runtime/models/environment/WorkItem.java +++ b/src/main/java/com/volcengine/ark/runtime/models/environment/WorkItem.java @@ -42,7 +42,6 @@ WorkItem.JSON_PROPERTY_STOP_REQUESTED_AT, WorkItem.JSON_PROPERTY_STOPPED_AT, WorkItem.JSON_PROPERTY_STOP_REASON, - WorkItem.JSON_PROPERTY_RECOVERY_COUNT, WorkItem.JSON_PROPERTY_TYPE }) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.21.0") @@ -99,10 +98,6 @@ public class WorkItem { @javax.annotation.Nullable private WorkStopReason stopReason; - public static final String JSON_PROPERTY_RECOVERY_COUNT = "recovery_count"; - @javax.annotation.Nullable - private Integer recoveryCount; - /** * 对象类型,固定为 `work`。 */ @@ -458,7 +453,7 @@ public WorkItem stopReason(@javax.annotation.Nullable WorkStopReason stopReason) } /** - * 最近一次停止原因。首次停止前省略;state 为 stopping / stopped 时返回本次停止原因; 自动恢复到 queued / starting / active 后仍保留上一次停止原因,当前生命周期状态以 `state` 为准。 + * 最近一次停止原因。首次停止前省略;state 为 stopping / stopped 时返回本次停止原因。原 owner 通过 Heartbeat 将 `stopped + lease_expired` 恢复为 active 时清除此字段。 * @return stopReason */ @javax.annotation.Nullable @@ -476,31 +471,6 @@ public void setStopReason(@javax.annotation.Nullable WorkStopReason stopReason) this.stopReason = stopReason; } - public WorkItem recoveryCount(@javax.annotation.Nullable Integer recoveryCount) { - - this.recoveryCount = recoveryCount; - return this; - } - - /** - * 自上次成功完成且全部 tool_use 已闭合后,平台已自动将本 Work 重新排队的次数; 首次执行或字段省略时按 0 处理。手动 Ensure 不会清零该计数。 - * @return recoveryCount - */ - @javax.annotation.Nullable - @JsonProperty(value = JSON_PROPERTY_RECOVERY_COUNT, required = false) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - - public Integer getRecoveryCount() { - return recoveryCount; - } - - - @JsonProperty(value = JSON_PROPERTY_RECOVERY_COUNT, required = false) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public void setRecoveryCount(@javax.annotation.Nullable Integer recoveryCount) { - this.recoveryCount = recoveryCount; - } - public WorkItem type(@javax.annotation.Nonnull TypeEnum type) { this.type = type; @@ -549,13 +519,12 @@ public boolean equals(Object o) { Objects.equals(this.stopRequestedAt, workItem.stopRequestedAt) && Objects.equals(this.stoppedAt, workItem.stoppedAt) && Objects.equals(this.stopReason, workItem.stopReason) && - Objects.equals(this.recoveryCount, workItem.recoveryCount) && Objects.equals(this.type, workItem.type); } @Override public int hashCode() { - return Objects.hash(id, acknowledgedAt, createdAt, data, environmentId, latestHeartbeatAt, tags, secret, startedAt, state, stopRequestedAt, stoppedAt, stopReason, recoveryCount, type); + return Objects.hash(id, acknowledgedAt, createdAt, data, environmentId, latestHeartbeatAt, tags, secret, startedAt, state, stopRequestedAt, stoppedAt, stopReason, type); } @Override @@ -575,7 +544,6 @@ public String toString() { sb.append(" stopRequestedAt: ").append(toIndentedString(stopRequestedAt)).append("\n"); sb.append(" stoppedAt: ").append(toIndentedString(stoppedAt)).append("\n"); sb.append(" stopReason: ").append(toIndentedString(stopReason)).append("\n"); - sb.append(" recoveryCount: ").append(toIndentedString(recoveryCount)).append("\n"); sb.append(" type: ").append(toIndentedString(type)).append("\n"); sb.append("}"); return sb.toString(); @@ -653,10 +621,6 @@ public WorkItem.Builder stopReason(WorkStopReason stopReason) { this.instance.stopReason = stopReason; return this; } - public WorkItem.Builder recoveryCount(Integer recoveryCount) { - this.instance.recoveryCount = recoveryCount; - return this; - } public WorkItem.Builder type(TypeEnum type) { this.instance.type = type; return this; @@ -708,7 +672,6 @@ public WorkItem.Builder toBuilder() { .stopRequestedAt(getStopRequestedAt()) .stoppedAt(getStoppedAt()) .stopReason(getStopReason()) - .recoveryCount(getRecoveryCount()) .type(getType()); } diff --git a/src/main/java/com/volcengine/ark/runtime/selfhosted/EnvironmentWorker.java b/src/main/java/com/volcengine/ark/runtime/selfhosted/EnvironmentWorker.java index 1f928a9..0756865 100644 --- a/src/main/java/com/volcengine/ark/runtime/selfhosted/EnvironmentWorker.java +++ b/src/main/java/com/volcengine/ark/runtime/selfhosted/EnvironmentWorker.java @@ -187,7 +187,8 @@ private void heartbeatLoop(ClaimedWork work, AtomicBoolean stop, AtomicReference work.environmentId, work.id, last, - (int) (ttl / 1000L)); + (int) (ttl / 1000L), + options.workerId); if (response == null) { if (System.currentTimeMillis() - lastSuccess > ttl) { cause.set("heartbeat_lost"); diff --git a/src/main/java/com/volcengine/ark/runtime/selfhosted/SelfHostedClient.java b/src/main/java/com/volcengine/ark/runtime/selfhosted/SelfHostedClient.java index dd04b25..6fb8760 100644 --- a/src/main/java/com/volcengine/ark/runtime/selfhosted/SelfHostedClient.java +++ b/src/main/java/com/volcengine/ark/runtime/selfhosted/SelfHostedClient.java @@ -122,6 +122,15 @@ public void ackWork(String environmentId, String workId, String workerId) { public HeartbeatWorkResponse heartbeatWork( String environmentId, String workId, String expectedLastHeartbeat, int desiredTTLSeconds) { + return heartbeatWork(environmentId, workId, expectedLastHeartbeat, desiredTTLSeconds, ""); + } + + public HeartbeatWorkResponse heartbeatWork( + String environmentId, + String workId, + String expectedLastHeartbeat, + int desiredTTLSeconds, + String workerId) { require(environmentId, "environmentId"); require(workId, "workId"); String expected = expectedLastHeartbeat == null || expectedLastHeartbeat.isEmpty() @@ -129,7 +138,7 @@ public HeartbeatWorkResponse heartbeatWork( : expectedLastHeartbeat; Integer ttl = desiredTTLSeconds > 0 ? desiredTTLSeconds : null; return execute(heartbeatApi.heartbeatEnvironmentWork( - environmentId, workId, expected, ttl, Collections.emptyMap())); + environmentId, workId, expected, ttl, workerHeader(workerId))); } public void stopWork(String environmentId, String workId, boolean force) { diff --git a/src/main/java/com/volcengine/ark/runtime/service/ArkService.java b/src/main/java/com/volcengine/ark/runtime/service/ArkService.java index 0ea2fc3..50163ad 100644 --- a/src/main/java/com/volcengine/ark/runtime/service/ArkService.java +++ b/src/main/java/com/volcengine/ark/runtime/service/ArkService.java @@ -650,8 +650,21 @@ public WorkItem ackEnvironmentWork(String environmentId, String workId, String w public HeartbeatWorkResponse heartbeatEnvironmentWork( String environmentId, String workId, String expectedLastHeartbeat, Integer desiredTTLSeconds) { + return heartbeatEnvironmentWork(environmentId, workId, expectedLastHeartbeat, desiredTTLSeconds, null); + } + + public HeartbeatWorkResponse heartbeatEnvironmentWork( + String environmentId, + String workId, + String expectedLastHeartbeat, + Integer desiredTTLSeconds, + String workerId) { + Map headers = new HashMap<>(); + if (workerId != null && !workerId.isEmpty()) { + headers.put("Ark-Worker-ID", workerId); + } return execute(api.heartbeatEnvironmentWork( - environmentId, workId, expectedLastHeartbeat, desiredTTLSeconds, new HashMap<>())); + environmentId, workId, expectedLastHeartbeat, desiredTTLSeconds, headers)); } public WorkItem stopEnvironmentWork(String environmentId, String workId, StopWorkBody body) { diff --git a/src/test/java/com/volcengine/ark/runtime/selfhosted/EnvironmentWorkerTest.java b/src/test/java/com/volcengine/ark/runtime/selfhosted/EnvironmentWorkerTest.java index cb89766..197d6d6 100644 --- a/src/test/java/com/volcengine/ark/runtime/selfhosted/EnvironmentWorkerTest.java +++ b/src/test/java/com/volcengine/ark/runtime/selfhosted/EnvironmentWorkerTest.java @@ -84,6 +84,7 @@ public void heartbeatStopCancelsRunnerBeforeEventPolling() throws Exception { Request request = chain.request(); String path = request.url().encodedPath(); if (path.endsWith("/heartbeat")) { + assertEquals("worker-1", request.header("Ark-Worker-ID")); heartbeat.countDown(); return response(request, "{\"state\":\"stopping\",\"lease_extended\":true}"); } @@ -115,7 +116,9 @@ public void heartbeatStopCancelsRunnerBeforeEventPolling() throws Exception { .build(); EnvironmentWorker worker = new EnvironmentWorker( client, - new EnvironmentWorker.Options().workdir(Files.createTempDirectory("ark-java-worker-").toString())); + new EnvironmentWorker.Options() + .workerId("worker-1") + .workdir(Files.createTempDirectory("ark-java-worker-").toString())); long started = System.nanoTime(); worker.handleItem(new EnvironmentWorker.HandleItemOptions() @@ -262,7 +265,7 @@ private static class NullHeartbeatClient extends SelfHostedClient { @Override public HeartbeatWorkResponse heartbeatWork( - String environmentId, String workId, String expectedLastHeartbeat, int desiredTTLSeconds) { + String environmentId, String workId, String expectedLastHeartbeat, int desiredTTLSeconds, String workerId) { heartbeats.incrementAndGet(); firstHeartbeat.countDown(); return null; @@ -296,7 +299,7 @@ private static class CloseClient extends SelfHostedClient { @Override public HeartbeatWorkResponse heartbeatWork( - String environmentId, String workId, String expectedLastHeartbeat, int desiredTTLSeconds) { + String environmentId, String workId, String expectedLastHeartbeat, int desiredTTLSeconds, String workerId) { return new HeartbeatWorkResponse() .state(WorkState.ACTIVE) .leaseExtended(Boolean.TRUE) @@ -339,7 +342,7 @@ private static class LeaseLostClient extends SelfHostedClient { @Override public HeartbeatWorkResponse heartbeatWork( - String environmentId, String workId, String expectedLastHeartbeat, int desiredTTLSeconds) { + String environmentId, String workId, String expectedLastHeartbeat, int desiredTTLSeconds, String workerId) { heartbeat.countDown(); throw new WorkerAPIException(412, "lease lost", ""); } @@ -373,7 +376,7 @@ private static class LeaseNotExtendedClient extends SelfHostedClient { @Override public HeartbeatWorkResponse heartbeatWork( - String environmentId, String workId, String expectedLastHeartbeat, int desiredTTLSeconds) { + String environmentId, String workId, String expectedLastHeartbeat, int desiredTTLSeconds, String workerId) { heartbeat.countDown(); return new HeartbeatWorkResponse() .state(WorkState.ACTIVE) diff --git a/src/test/java/com/volcengine/ark/runtime/selfhosted/SelfHostedClientTest.java b/src/test/java/com/volcengine/ark/runtime/selfhosted/SelfHostedClientTest.java index 3e9f1e4..243a7a9 100644 --- a/src/test/java/com/volcengine/ark/runtime/selfhosted/SelfHostedClientTest.java +++ b/src/test/java/com/volcengine/ark/runtime/selfhosted/SelfHostedClientTest.java @@ -49,8 +49,7 @@ public void preservesNestedSessionWorkData() { + "\"id\":\"work-1\"," + "\"environment_id\":\"env-1\"," + "\"data\":{\"id\":\"session-1\",\"type\":\"session\"}," - + "\"stop_reason\":\"worker_abnormal\"," - + "\"recovery_count\":5" + + "\"stop_reason\":\"worker_abnormal\"" + "}"; OkHttpClient httpClient = new OkHttpClient.Builder() .addInterceptor(chain -> response(chain.request(), new AtomicReference<>(), body)) @@ -67,7 +66,6 @@ public void preservesNestedSessionWorkData() { assertEquals("env-1", item.getEnvironmentId()); assertEquals("session-1", item.getData().getId()); assertEquals(WorkStopReason.WORKER_ABNORMAL, item.getStopReason()); - assertEquals(Integer.valueOf(5), item.getRecoveryCount()); assertEquals("session-1", WorkItems.sessionId(item)); } @@ -336,6 +334,7 @@ public void atomicEnvironmentWorkAPIMatchesOpenAPIContract() throws Exception { request.url().encodedPath()); assertEquals("NO_HEARTBEAT", request.url().queryParameter("expected_last_heartbeat")); assertEquals("30", request.url().queryParameter("desired_ttl_seconds")); + assertEquals("worker-1", request.header("Ark-Worker-ID")); return response(request, new AtomicReference<>(), heartbeat); } assertEquals("POST", request.method()); @@ -360,7 +359,7 @@ public void atomicEnvironmentWorkAPIMatchesOpenAPIContract() throws Exception { client.ackWork("env-1", "work-1", "worker-1"); assertEquals( "2026-08-24T10:00:01Z", - client.heartbeatWork("env-1", "work-1", "NO_HEARTBEAT", 30).getLastHeartbeat()); + client.heartbeatWork("env-1", "work-1", "NO_HEARTBEAT", 30, "worker-1").getLastHeartbeat()); client.stopWork("env-1", "work-1", false); assertEquals(4, calls.get());