What is the lifecycle and/or ownership of the incoming request body stream in ASP.NET Core? And how can I...












0















In my ASP.NET Core Web API, desktop client software will upload large binary HTTP requests (potentially gigagbytes). I want to process these in the background and return a response to the client if processing fails to complete within a set timeout of a few seconds.



Currently my processing code reads the request stream directly - which means the life-cycle of the request Stream needs to outlast the Request/Response - however I was not able to find any documentation regarding how to transfer ownership of the Request's stream to prevent it from being Closed/Disposed immediately after the controller response completes.



Here's a basic example:



class BigDataController : ControllerBase
{
[HttpPost("data")]
public async Task<IActionResult> ReceiveData()
{
Task processTask = this.ProcessDataAsync( this.Request.Body );
Task timeoutTask = Task.Delay( 5000 );

Task completed = await Task.WhenAny( processTask, timeoutTask );
if( completed == timeoutTask )
{
return this.OK( "Still processing, please check back later..." );
}
else
{
return this.Ok( "Processing completed." );
}
}

private async Task ProcessDataAsync( Stream stream )
{
using( StreamReader rdr = new StreamReader( stream ) )
{
// etc
}
}
}


In the event that ProcesDataAsync takes longer than 5 seconds to run the ReceiveData controller action will return a response to the client and ASP.NET will dispose of the request's body stream. I don't want this to happen, obviously.



While a workaround is to perform a stream copy to a MemoryStream or other persistent storage and then process that data, I have concerns it will not scale well to the potentially gigabyte-sized requests I expect to receive.



If this is actually by-design, then what proven strategies exist to proxy or otherwise abstract-away the incoming request stream via a persistent buffer to prevent the closure of the request/response pair from interrupting my ProcessDataAsync method?










share|improve this question



























    0















    In my ASP.NET Core Web API, desktop client software will upload large binary HTTP requests (potentially gigagbytes). I want to process these in the background and return a response to the client if processing fails to complete within a set timeout of a few seconds.



    Currently my processing code reads the request stream directly - which means the life-cycle of the request Stream needs to outlast the Request/Response - however I was not able to find any documentation regarding how to transfer ownership of the Request's stream to prevent it from being Closed/Disposed immediately after the controller response completes.



    Here's a basic example:



    class BigDataController : ControllerBase
    {
    [HttpPost("data")]
    public async Task<IActionResult> ReceiveData()
    {
    Task processTask = this.ProcessDataAsync( this.Request.Body );
    Task timeoutTask = Task.Delay( 5000 );

    Task completed = await Task.WhenAny( processTask, timeoutTask );
    if( completed == timeoutTask )
    {
    return this.OK( "Still processing, please check back later..." );
    }
    else
    {
    return this.Ok( "Processing completed." );
    }
    }

    private async Task ProcessDataAsync( Stream stream )
    {
    using( StreamReader rdr = new StreamReader( stream ) )
    {
    // etc
    }
    }
    }


    In the event that ProcesDataAsync takes longer than 5 seconds to run the ReceiveData controller action will return a response to the client and ASP.NET will dispose of the request's body stream. I don't want this to happen, obviously.



    While a workaround is to perform a stream copy to a MemoryStream or other persistent storage and then process that data, I have concerns it will not scale well to the potentially gigabyte-sized requests I expect to receive.



    If this is actually by-design, then what proven strategies exist to proxy or otherwise abstract-away the incoming request stream via a persistent buffer to prevent the closure of the request/response pair from interrupting my ProcessDataAsync method?










    share|improve this question

























      0












      0








      0








      In my ASP.NET Core Web API, desktop client software will upload large binary HTTP requests (potentially gigagbytes). I want to process these in the background and return a response to the client if processing fails to complete within a set timeout of a few seconds.



      Currently my processing code reads the request stream directly - which means the life-cycle of the request Stream needs to outlast the Request/Response - however I was not able to find any documentation regarding how to transfer ownership of the Request's stream to prevent it from being Closed/Disposed immediately after the controller response completes.



      Here's a basic example:



      class BigDataController : ControllerBase
      {
      [HttpPost("data")]
      public async Task<IActionResult> ReceiveData()
      {
      Task processTask = this.ProcessDataAsync( this.Request.Body );
      Task timeoutTask = Task.Delay( 5000 );

      Task completed = await Task.WhenAny( processTask, timeoutTask );
      if( completed == timeoutTask )
      {
      return this.OK( "Still processing, please check back later..." );
      }
      else
      {
      return this.Ok( "Processing completed." );
      }
      }

      private async Task ProcessDataAsync( Stream stream )
      {
      using( StreamReader rdr = new StreamReader( stream ) )
      {
      // etc
      }
      }
      }


      In the event that ProcesDataAsync takes longer than 5 seconds to run the ReceiveData controller action will return a response to the client and ASP.NET will dispose of the request's body stream. I don't want this to happen, obviously.



      While a workaround is to perform a stream copy to a MemoryStream or other persistent storage and then process that data, I have concerns it will not scale well to the potentially gigabyte-sized requests I expect to receive.



      If this is actually by-design, then what proven strategies exist to proxy or otherwise abstract-away the incoming request stream via a persistent buffer to prevent the closure of the request/response pair from interrupting my ProcessDataAsync method?










      share|improve this question














      In my ASP.NET Core Web API, desktop client software will upload large binary HTTP requests (potentially gigagbytes). I want to process these in the background and return a response to the client if processing fails to complete within a set timeout of a few seconds.



      Currently my processing code reads the request stream directly - which means the life-cycle of the request Stream needs to outlast the Request/Response - however I was not able to find any documentation regarding how to transfer ownership of the Request's stream to prevent it from being Closed/Disposed immediately after the controller response completes.



      Here's a basic example:



      class BigDataController : ControllerBase
      {
      [HttpPost("data")]
      public async Task<IActionResult> ReceiveData()
      {
      Task processTask = this.ProcessDataAsync( this.Request.Body );
      Task timeoutTask = Task.Delay( 5000 );

      Task completed = await Task.WhenAny( processTask, timeoutTask );
      if( completed == timeoutTask )
      {
      return this.OK( "Still processing, please check back later..." );
      }
      else
      {
      return this.Ok( "Processing completed." );
      }
      }

      private async Task ProcessDataAsync( Stream stream )
      {
      using( StreamReader rdr = new StreamReader( stream ) )
      {
      // etc
      }
      }
      }


      In the event that ProcesDataAsync takes longer than 5 seconds to run the ReceiveData controller action will return a response to the client and ASP.NET will dispose of the request's body stream. I don't want this to happen, obviously.



      While a workaround is to perform a stream copy to a MemoryStream or other persistent storage and then process that data, I have concerns it will not scale well to the potentially gigabyte-sized requests I expect to receive.



      If this is actually by-design, then what proven strategies exist to proxy or otherwise abstract-away the incoming request stream via a persistent buffer to prevent the closure of the request/response pair from interrupting my ProcessDataAsync method?







      asp.net-core






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 28 '18 at 10:25









      DaiDai

      73.7k13118205




      73.7k13118205
























          0






          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53517227%2fwhat-is-the-lifecycle-and-or-ownership-of-the-incoming-request-body-stream-in-as%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53517227%2fwhat-is-the-lifecycle-and-or-ownership-of-the-incoming-request-body-stream-in-as%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

          Calculate evaluation metrics using cross_val_predict sklearn

          Insert data from modal to MySQL (multiple modal on website)