【问题标题】:How can I implement resource synchronization across multiple ServiceStack service calls split among multiple services?如何在多个服务之间拆分的多个 ServiceStack 服务调用之间实现资源同步?
【发布时间】:2013-02-20 00:47:41
【问题描述】:

我想创建一组 ServiceStack 服务,托管在同一个主机应用程序中,它们都将使用一组共享的文件资源。为了防止冲突,我打算创建同步代码(又名锁定)来防止文件上的读/写冲突。

如果我只想在单个服务方法调用期间锁定文件,解决方案很简单。例如,我可以创建一个同步的全局对象,通过 Session Key 跟踪锁。但是,我希望客户端应用程序能够在对不同 ServiceStack 服务中不同方法的 MULTIPLE 调用期间锁定文件资源。

实现这一点的最佳方法是什么(或者这是人们会告诉我我不应该这样做的问题之一)?

这是我目前所考虑的:

  1. 如果我可以在多个 ServiceStack 服务之间共享一个 ISession 对象,我可以根据 Session 键跟踪文件锁。但是我无论如何都找不到这样做。这需要与使用 JsonServiceClient 对象的 C# 客户端一起工作,每个 ServiceStack 服务都会有一个这样的对象,并且它们每个都会在服务端生成一个单独的 ISession。

  2. 如果我实施了身份验证,我可以通过经过身份验证的用户 ID 来跟踪锁,但是两个不同的人可能使用相同的登录,在这种情况下他们不能共享资源锁。

  3. 我可以将我所有的服务方法组合成一个服务,然后共享一个会话。这将意味着创建一个复杂的请求对象,该对象将是几个可能的请求的组合。这可能不像听起来那样可怕。请求对象可以是用自定义 SQL 语言编写的查询字符串,我的服务将解析并运行该查询。我不想这样做,因为它需要更多的编码工作(尽管如果有人知道用于自定义 SQL 语言的免费、强大的解析工具,我可能会考虑它)。

  4. 创建一个分配事务 ID 的事务服务。如果客户端想要持有锁,它必须首先从 Transaction 服务获取一个事务 ID,并将此 ID 传递给每个后续服务调用(这将是每个请求类中的可选属性)。这实际上与在服务之间共享会话(或者更确切地说,会话密钥)没有太大区别,但我正在让客户端做一些工作。呵呵。

【问题讨论】:

    标签: transactions locking servicestack


    【解决方案1】:

    我对您所说的服务有点迷茫,您可以在一个应用程序主机上拥有多个,并且使用会话机制将允许您在服务之间共享特定的客户端会话。服务堆栈中的会话使用您已注册的ICacheClient,因此如果您有一个服务器场,您可以使用RedisCacheClient 之类的东西在运行同一应用程序主机的多个服务器之间共享您的会话信息。如果您想锁定文件,您也可以将此信息存储在ICacheClient 中。所以你可以这样做:

    public class FileLock
    {
        public string ClientId { get; set; }
        public string FileId { get; set; }
    }
    
    public class FileLockService : Service
    {
        public object Post(FileLock req)
        {
            // this will only be added to the cache if it doesn't exist
            // but understand that the cache key needs to be unique
            // within the entire system, so qualify it with a urn...
            var wasAbleToLock = Cache.Add("file:lock:" + req.FileId, req.ClientId);
    
            return wasAbleToLock;
        }
    
        public object Get(FileLock req)
        {
            // return the client id for who ever has the lock
            return Cache.Get("file:lock:" + req.FileId);
        }
    }
    

    【讨论】:

    • “服务”是指实现 ServiceStack.ServiceInterface.Service 的类的实例化。关键是,我如何获得两个单独的服务来“共享特定的客户端会话”?我不知道该怎么做。在单个 C# 客户端程序中,如果我使用两个单独的 JsvServiceClient 对象调用两个单独的服务,它们每个都会自动生成自己的 Session。
    • 我明白你在说什么,你实际上想在客户端之间共享会话状态。我假设您对客户端进行某种身份验证。如果是这样,只需获取会话之间的公共密钥,例如UserId 并使用它来锁定文件。现在,如果您只有一个客户端,但正在拨打多个电话,您可以多次使用相同的JsonServiceClient。通常在进行集成测试时,我会创建一个服务客户端,进行身份验证调用(它在内部存储会话 cookie),然后使用同一个客户端进行其他几次调用。
    猜你喜欢
    • 2019-09-30
    • 2021-12-16
    • 2019-12-25
    • 1970-01-01
    • 2017-08-16
    • 2015-06-19
    • 2022-01-27
    • 1970-01-01
    • 2014-04-26
    相关资源
    最近更新 更多