1

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

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

完成此任务的最佳方法是什么(或者这是人们会告诉我我不应该这样做的那些问题之一)?

这是我到目前为止所考虑的:

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

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

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

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

4

1 回答 1

2

我对您所说的服务有点迷茫,您可以在一个应用程序主机上拥有多个,并且使用会话机制将允许您在服务之间共享特定的客户端会话。服务堆栈中的会话使用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);
    }
}
于 2013-03-05T17:51:20.000 回答