首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过GUID检查Microsoft Orleans中是否存在谷物

通过GUID检查Microsoft Orleans中是否存在谷物
EN

Stack Overflow用户
提问于 2017-05-02 18:41:55
回答 1查看 2K关注 0票数 9

如何检查特定Id是否已经存在谷物?

考虑到下面的代码将创建一个新的播放器粒,如果Id不存在,它将传递给GetGrain(),我不知道如何检查是否已经存在了。

代码语言:javascript
复制
public async Task<Guid> Create(Guid playerGuid)
    {
        var player = GrainClient.GrainFactory.GetGrain<IPlayerGrain>(playerGuid);
        var gameGuid = await player.CreateGame();

        return gameGuid;
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-02 21:41:26

简单地说,就是储存一些状态,这样谷物就知道它以前是否被激活了。

在新奥尔良,谷物从来不会被明确地创建或销毁:它们总是可以用来处理请求。因此,从技术上讲,谷物是否存在的概念并不适用于新奥尔良。另一方面,我们可以问“有一粒与这个id曾经被激活过”。

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

  1. 谷物从来没有被激活过,但你希望它已经激活了。我在IPlayerGrain上调用一个方法,但是播放器不存在。
  2. 谷物以前已经被激活了,但是你期望它没有被激活。我正试图为这个玩家创建一个新的游戏,但是这个id已经被拿走了。

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

  1. 如果以前从未创建过播放机,则对IPlayerGrain.CreateGame()的调用将引发异常。忽略这样一个事实:我从不设置Created,这可以在某些CreatePlayer(...)方法中完成。
  2. 如果游戏已经创建,对IGameGrain.TryCreateGame(player)的调用将返回false。在这种情况下,IPlayerGrain.CreateGame()将继续循环,直到找到一个尚未创建的游戏。有了Guid id,你就不太可能看到碰撞,但我理解谨慎的愿望--以防星星对着你。
代码语言:javascript
复制
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;
    }
}
代码语言:javascript
复制
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方法不需要更改。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43745031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档