繁体   English   中英

奥尔良粮食上的任务调用结果

[英]Result of task invocation on a grain in Orleans

对于很长的问题,我深表歉意。 我一直在与奥尔良进行试验,以了解其各种特性,并且从逻辑上讲,这些问题都归根结底。


第一个测试涉及每1秒从客户端向特定的谷物发出请求,而谷物则需要10秒执行请求。 代码是这样的:

// client code
while (1)
{
    Console.WriteLine("Client giving another request");
    double temperature = random.NextDouble() * 40;
    var sensor = client.GetGrain<ITemperatureSensorGrain>(500);
    Task t = sensor.SubmitTemperatureAsync((float)temperature);
    Console.WriteLine(t.Status);
    Thread.Sleep(1000);
 }

// grain code
public Task SubmitTemperatureAsync(float temperature)
{
    long grainId = this.GetPrimaryKeyLong();
    Console.WriteLine($"{grainId} outer received temperature: {temperature}");
    Thread.Sleep(10000);

    Console.WriteLine($"{grainId} outer complete");
    return Task.CompletedTask;
}

控制台输出为:

Client giving another request
Task Status - WaitingForActivation
500 outer received temperature: 32.29987    <------------ print statement inside grain
Client giving another request     <--------------------- client continues
Task Status - WaitingForActivation  <------------------- client isn't blocked
Client giving another request
Task Status - WaitingForActivation
Client giving another request
Task Status - WaitingForActivation
Client giving another request
Task Status - WaitingForActivation
Client giving another request
Task Status - WaitingForActivation
Client giving another request
Task Status - WaitingForActivation
Client giving another request
Task Status - WaitingForActivation
Client giving another request
Task Status - WaitingForActivation
Client giving another request
Task Status - WaitingForActivation
Client giving another request
Task Status - WaitingForActivation
500 outer complete

由于奥尔良的谷物是单线程的,因此只有第一个请求被调用,其余的请求在谷物侧排队。 我对此部分的问题是:-

在普通的C#中,当调用async方法时,它将继续在主线程上运行,直到当它以另一个Task的形式启动等待的表达式并返回该Task时,它一直命中await语句。 因此,调用方被阻塞,直到命中await语句为止。 同样,这里的客户端也应该被阻塞10秒钟,之后第一个谷物请求返回一个Task。 但是,这不会发生。 客户端将继续计划任务而不会被阻塞。

  • 那么,客户端FireAndForget调用谷物吗?
  • 如果是,那么他们如何取回Task对象?
  • 当客户端调用谷物对象并且运行时将Task对象带回客户端时,是否存在任何类型的阻止?

第二个测试涉及从一个谷物向一个谷物发出请求,第二个谷物在返回之前等待10秒钟。 代码是这样的:

// client code
while (1)
{
    Console.WriteLine("Client giving another request");
    double temperature = random.NextDouble() * 40;
    var sensor = client.GetGrain<ITemperatureSensorGrain>(500);
    Task t = sensor.SubmitTemperatureAsync((float)temperature);
    Console.WriteLine("Client Task Status - "+t.Status);

    // make client sleep for a long time after the first request
    // because we don't want any more requests from the client
    Thread.Sleep(1000000000);
}

// outer-grain (ITemperatureSensorGrain) code
public async Task SubmitTemperatureAsync(float temperature)
{
    long grainId = this.GetPrimaryKeyLong();
    Console.WriteLine($"{grainId} outer received temperature: {temperature}");

    while(true)
    {
        Console.WriteLine("Grain sending another request");
        ITempBGrain sensor = this.GrainFactory.GetGrain<ITempBGrain>(400);
        // await sensor.SubmitTempBAsync(temperature);
        Task t = sensor.SubmitTempBAsync(temperature);
        Console.WriteLine("Grain Task Status - "+t.Status);
        Thread.Sleep(1000);
    }
}

// inner-grain (ITempBGrain) code
public Task SubmitTempBAsync(float temperature)
{
    long grainId = this.GetPrimaryKeyLong();
    Console.WriteLine($"{grainId} internal received temperature: {temperature}");
    Thread.Sleep(10000);
    Console.WriteLine($"{grainId} internal complete");
    return Task.CompletedTask;
}

控制台输出为:

Client giving another request
Client Task Status - WaitingForActivation
500 outer received temperature: 10.36764
Grain sending another request       <-------------- Outer grain prints
Grain Task Status - WaitingForActivation 
Grain sending another request  <----------- Inner grain doesn't print
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
Grain sending another request
Grain Task Status - WaitingForActivation
warn: Orleans.Runtime.CallbackData[100157]
      Response did not arrive on time in 00:00:30 for message: Request *cli/015ba7a5@d4cdc7ab->S127.0.0.1:30000:0*grn/6424EE47/000001f4 #17: . Target History is: <S127.0.0.1:30000:0:*grn/6424EE47/000001f4:>. About to break its promise.
Grain sending another request
Grain Task Status - WaitingForActivation

我在这里看到的内容与第一个实验中客户端发生的情况类似。 因此,这些问题仍然存在。 但是,这里发生了另一件事。 内部谷物的控制台输出无处显示。 为什么内部粮食没有执行? 如果我启用外部代码中的注释行,并等待内部任务,则显示以下输出,该输出似乎有效。

Client giving another request
Client Task Status - WaitingForActivation
500 outer received temperature: 6.332514
Grain sending another request
400 internal received temperature: 6.332514
400 internal complete
Grain sending another request
400 internal received temperature: 6.332514

第一部分
不,调用谷物时没有阻塞。 帖子进一步澄清了进行谷物调用时会发生什么。

第二部分
尽管谷物是单线程的是正确的,但假设每个谷物在奥尔良都有自己的线程是错误的。 正如@Tseng所说, Orleans uses the async feature of .NET Core. It will process a grain until an async operation happens. Then it returns the thread to the thread-pool. This thread can be used by another grain to process data until the async operation is complete. When its complete, it resumes. its not necessary the same thread (but its the same context) Orleans uses the async feature of .NET Core. It will process a grain until an async operation happens. Then it returns the thread to the thread-pool. This thread can be used by another grain to process data until the async operation is complete. When its complete, it resumes. its not necessary the same thread (but its the same context) Orleans uses the async feature of .NET Core. It will process a grain until an async operation happens. Then it returns the thread to the thread-pool. This thread can be used by another grain to process data until the async operation is complete. When its complete, it resumes. its not necessary the same thread (but its the same context) 第一个谷物阻塞了线程,第二个谷物没有机会执行。

感谢曾和鲁本·邦德(Ruben Bond)讲清楚的事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM