簡體   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