Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/ray/core_worker/actor_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,19 @@ bool ActorManager::AddActorHandle(std::unique_ptr<ActorHandle> actor_handle,
}

void ActorManager::OnActorKilled(const ActorID &actor_id) {
MarkActorKilledOrOutOfScope(GetActorHandle(actor_id));
auto actor_handle = GetActorHandleIfExists(actor_id);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The use of GetActorHandleIfExists is correct to fix the crash. On a related note, I noticed that GetActorHandleIfExists is not const, unlike its counterpart GetActorHandle. Since it only performs a read operation, making it const would improve const-correctness.

This is a minor suggestion for code quality that could be addressed here or in a follow-up. For context, the change would look like this:

// In actor_manager.h
std::shared_ptr<ActorHandle> GetActorHandleIfExists(const ActorID &actor_id) const;

// In actor_manager.cc
std::shared_ptr<ActorHandle> ActorManager::GetActorHandleIfExists(
    const ActorID &actor_id) const { /* ... */ }

if (actor_handle == nullptr) {
// The actor handle may not exist if:
// 1. The actor was created in a previous Ray session and the user is trying
// to kill it after ray.shutdown() and ray.init().
// 2. The actor handle was already removed for some other reason.
// In these cases, we simply log a warning and return instead of crashing.
RAY_LOG(WARNING) << "Cannot find actor handle for actor_id " << actor_id
<< ". The actor may have been created in a different Ray session "
<< "or already been cleaned up.";
return;
}
MarkActorKilledOrOutOfScope(actor_handle);
}

void ActorManager::WaitForActorRefDeleted(
Expand Down
17 changes: 17 additions & 0 deletions src/ray/core_worker/tests/actor_manager_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,23 @@ TEST_F(ActorManagerTest, TestNamedActorIsKilledBeforeSubscribeFinished) {
ASSERT_TRUE(actor_manager_->GetCachedNamedActorID(cached_actor_name).IsNil());
}

// Test that OnActorKilled does not crash when the actor handle does not exist.
// This can happen when the actor was created in a previous Ray session.
// Fixes https://github.com/ray-project/ray/issues/59340
TEST_F(ActorManagerTest, TestOnActorKilledWithNonExistentHandle) {
// Create a random actor ID that does not have a registered handle.
ActorID non_existent_actor_id = ActorID::Of(JobID::FromInt(1), TaskID::Nil(), 1);

// Verify that the actor handle does not exist.
ASSERT_FALSE(actor_manager_->CheckActorHandleExists(non_existent_actor_id));

// Call OnActorKilled with a non-existent actor ID.
// This should NOT crash - it should log a warning and return gracefully.
actor_manager_->OnActorKilled(non_existent_actor_id);

// The test passes if we reach here without crashing.
}

} // namespace core
} // namespace ray

Expand Down