首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Orleans grains中的单线程

Orleans grains中的单线程
EN

Stack Overflow用户
提问于 2018-07-26 04:41:22
回答 1查看 734关注 0票数 2

我正在尝试理解Microsoft Orleans中的单线程粒度。我使用了here中的代码,并对其进行了一些修改以测试我的场景。

我的客户端代码和思洛存储器构建代码

代码语言:javascript
复制
    static async Task Main(string[] args)
    {
        var siloBuilder = new SiloHostBuilder()
            .UseLocalhostClustering()
            .UseDashboard(options => { })
            .Configure<ClusterOptions>(options =>
            {
                options.ClusterId = "dev";
                options.ServiceId = "Orleans2GettingStarted";
            })
            .Configure<EndpointOptions>(options =>
                options.AdvertisedIPAddress = IPAddress.Loopback)
            .ConfigureLogging(logging => logging.SetMinimumLevel(LogLevel.Warning).AddConsole());

        using (var host = siloBuilder.Build())
        {
            await host.StartAsync();

            var clientBuilder = new ClientBuilder()
                .UseLocalhostClustering()
                .Configure<ClusterOptions>(options =>
                {
                    options.ClusterId = "dev";
                    options.ServiceId = "Orleans2GettingStarted";
                })
                .ConfigureLogging(logging => logging.AddConsole());

            using (var client = clientBuilder.Build())
            {
                await client.Connect();

                var random = new Random();
                string sky = "blue";

                while (sky == "blue") // if run in Ireland, it exits loop immediately
                {
                    Console.WriteLine("Client giving another request");
                    int grainId = random.Next(0, 500);
                    double temperature = random.NextDouble() * 40;
                    var sensor = client.GetGrain<ITemperatureSensorGrain>(grainId);

                    // Not awaiting this task so that next call to grain 
                    // can be made without waiting for current call to complete
                    Task t = sensor.SubmitTemperatureAsync((float)temperature);
                    Thread.Sleep(1000);
                }
            }
        }
    }

My grain接口和实际grain实现

代码语言:javascript
复制
public interface ITemperatureSensorGrain : IGrainWithIntegerKey
{
    Task SubmitTemperatureAsync(float temperature);
}


public class TemperatureSensorGrain : Grain, ITemperatureSensorGrain
{
    public async Task SubmitTemperatureAsync(float temperature)
    {
        long grainId = this.GetPrimaryKeyLong();
        Console.WriteLine($"{grainId} received temperature: {temperature}");

        await Task.Delay(10000);
        // Thread.Sleep(10000);
        Console.WriteLine($"{grainId} complete");
        // return Task.CompletedTask;
    }
}

我基本上所做的是每隔1秒向grains发送一次请求,而我允许grains中的每个方法调用至少需要10秒。现在,根据grains的单线程执行和Orleans Runtime Scheduling描述的here我预计请求将被排队,除非当前请求的方法完成,否则下一个请求将不会被grains接收。然而,控制台的输出并没有证实这一点。控制台输出为:

代码语言:javascript
复制
Client giving another request
344 received temperature: 8.162848
Client giving another request
357 received temperature: 10.32219
Client giving another request
26 received temperature: 1.166182
Client giving another request
149 received temperature: 37.74038
Client giving another request
60 received temperature: 26.72013
Client giving another request
218 received temperature: 24.19116
Client giving another request
269 received temperature: 17.1897
Client giving another request
318 received temperature: 8.562404
Client giving another request
372 received temperature: 8.865559
Client giving another request
443 received temperature: 5.254442
Client giving another request
344 complete        <-------------- The first request completed here
97 received temperature: 19.24687

这清楚地表明,在当前请求完成之前,粒度正在处理下一个请求。

问题:

  • 另外,当我在粒度中使用Thread.sleep(10000)而不是Task.Delay(10000)时,我得到了几乎相同的控制台输出,除了每个请求调用的额外警告- Task [Id=1, Status=RanToCompletion] in WorkGroup [Activation: S127.0.0.1:11111:270246987*grn/6424EE47/00000028@cafcc6a5 #GrainType=Orleans2GettingStarted.TemperatureSensorGrain Placement=RandomPlacement State=Valid] took elapsed time 0:00:10.0019256 for execution, which is longer than 00:00:00.2000000。这是否意味着理想情况下每个颗粒都应该在200ms内处理?如果颗粒处理的时间更长,会发生什么?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-26 05:06:59

正如@DanWilson在评论中所说,你正在观察这种行为,因为每个调用都是在一个单独的粒度上进行的。

在Orleans中,每个颗粒都是有效的单线程,但不是整个竖井或集群。这意味着可以同时执行多个scale,这意味着向主机添加更多内核或添加更多机器将允许您扩展服务。

将您的代码修改为只选择一次grainId (通过将其移出循环),我可以看到以下示例执行:

代码语言:javascript
复制
137 received temperature: 18.74616
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
137 complete
137 received temperature: 20.03226
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
Client giving another request
137 complete
137 received temperature: 21.4471

这正是您所期望的:许多请求正在排队(每秒一个),但是每个请求需要10秒才能完成,然后颗粒才能开始处理下一个请求。

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

https://stackoverflow.com/questions/51527335

复制
相关文章

相似问题

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