gpt4 book ai didi

orleans - 通过 Microsoft Orleans 中的 GUID 检查grain是否存在

转载 作者:行者123 更新时间:2023-12-02 02:05:44 24 4
gpt4 key购买 nike

如何检查某个特定 ID 的grain是否已经存在?

考虑到下面将使用我传递给 GetGrain() 的 Id 创建一个新的玩家 Grain(如果它不存在),我不知道如何检查是否已经存在。

public async Task<Guid> Create(Guid playerGuid)
{
var player = GrainClient.GrainFactory.GetGrain<IPlayerGrain>(playerGuid);
var gameGuid = await player.CreateGame();

return gameGuid;
}

最佳答案

简单的答案是存储一些状态,以便grain知道它之前是否已被激活。

奥尔良中的 Grain 永远不会显式创建或销毁:它们始终可用于处理请求。因此,从技术上讲, Cereal 是否存在的概念不适用于奥尔良。另一方面,我们可以询问“之前是否曾激活过具有此 id 的grain”。

您可能需要检查两种情况:

  1. Cereal 从未被激活,但你期望它已经被激活。例如:我正在调用 IPlayerGrain 上的方法,但播放器不存在。
  2. Cereal 之前已被激活,但您期望它没有被激活。例如:我正在尝试为该玩家创建一个新游戏,但该 ID 已被占用。

在下面的代码示例中,您可以看到这两种情况:

  1. 如果之前从未创建过玩家,则对 IPlayerGrain.CreateGame() 的调用将引发异常。请忽略我从未设置 Created 的事实,这可以在某些 CreatePlayer(...) 方法中完成。
  2. 如果游戏已创建,则对 IGameGrain.TryCreateGame(player) 的调用将返回 false。在这种情况下,IPlayerGrain.CreateGame() 将继续循环,直到找到尚未创建的游戏。使用Guid id,您不太可能会看到碰撞,但我理解谨慎的愿望 - 以防万一星星对齐并密谋反对您。
public interface IPlayerGrain : IGrainWithGuidKey
{
Task<Guid> CreateGame();
}

public class PlayerState
{
public bool Created { get; set; }
}

public class PlayerGrain : Grain<PlayerState>, IPlayerGrain
{
public async Task<Guid> CreateGame()
{
if (!this.State.Created)
throw new InvalidOperationException("Player does not exist.");

var thisPlayer = this.AsReference<IPlayerGrain>();

var created = false;
var gameId = default(Guid);
while (!created)
{
// Get a new, random game grain
gameId = Guid.NewGuid();

// Try to create a game.
created = await this.GrainFactory.GetGrain<IGameGrain>(gameId)
.TryCreateGame(thisPlayer);

// If the game was successfully created, break out and return the id.
// Otherwise, keep looping.
}

return gameId;
}
}
public interface IGameGrain : IGrainWithGuidKey
{
// Returns true if game was created, false otherwise.
Task<bool> TryCreateGame(IPlayerGrain player);
}

public class GameState
{
public IPlayerGrain Player { get; set; }
}

public class GameGrain : Grain<GameState>, IGameGrain
{
public async Task<bool> TryCreateGame(IPlayerGrain player)
{
// If this grain already has a player, return false.
if (this.State.Player != null) return false;

// Otherwise, set the player, write it to storage, and return true.
this.State.Player = player;
await this.WriteStateAsync();
return true;
}
}

您问题中的Create方法不需要更改。

关于orleans - 通过 Microsoft Orleans 中的 GUID 检查grain是否存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43745031/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com