Skip to content

StubbedActorContext.scheduleOnce 返回预取消的 Cancellable #3219

Description

@He-Pin

Motivation

StubbedActorContext.scheduleOnce 返回的 Cancellable 处于预取消状态:cancel() 返回 false(表示取消失败),isCancelled 返回 true(表示已取消)。这使得测试中无法正确验证定时器的取消行为。

当前代码行为

StubbedActorContext.scala 中:

// StubbedActorContext.scala:162-166
override def scheduleOnce(delay: FiniteDuration, runnable: Runnable)(
    implicit executor: ExecutionContext): classic.Cancellable =
  new classic.Cancellable {
    def cancel(): Boolean = false  // 取消失败
    def isCancelled: Boolean = true  // 但声称已取消
  }

cancel() 返回 false 表示"取消操作未成功",而 isCancelled 返回 true 表示"已被取消",两者语义矛盾。

预期行为

返回的 Cancellable 应该语义一致:

  • 如果定时器可取消:cancel() 返回 trueisCancelled 变为 true
  • 如果定时器已执行:cancel() 返回 falseisCancelledfalse

代码证据

  • actor-testkit-typed/src/main/scala/org/apache/pekko/actor/testkit/typed/internal/StubbedActorContext.scala:162-166 — 预取消的 Cancellable 实现

复现方式

val context = new StubbedActorContext[String](self = TestProbe().ref, system = system)
val cancellable = context.scheduleOnce(1.second, () => ())
assert(cancellable.cancel() == false)  // 取消失败
assert(cancellable.isCancelled == true)  // 但已取消?矛盾

影响范围

  • 模块:pekko-actor-testkit-typed
  • 影响使用 BehaviorTestKit 测试定时器取消逻辑的代码
  • 测试可能因语义矛盾而无法正确验证定时器行为

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions