title: Kotlin Coroutines - Suspend function returning a Flow runs forever
body: <p>I am making a network repository that supports multiple data retrieval configs, therefore I want to separate those configs' logic into functions.</p>
  <p>However, I have a config that fetches the data continuously at specified intervals. Everything is fine when I emit those values to the original Flow. But when I take the logic into another function and return another Flow through it, it stops caring about its coroutine scope. Even after the scope's cancelation, it keeps on fetching the data.</p>
  <p><strong>TLDR:</strong> Suspend function returning a flow runs forever when currentCoroutineContext is used to control its loop's termination.</p>
  <p>What am I doing wrong here?
  Here's the simplified version of my code:</p>
  <p><em><strong>Fragment calling the viewmodels function that basically calls the getData()</strong></em></p>
  <pre><code> lifecycleScope.launch {
              viewModel.getLatestDataList()
          }
  </code></pre>
  <p><em><strong>Repository</strong></em></p>
  <pre><code>suspend fun getData(config: MyConfig): Flow&lt;List&lt;Data&gt;&gt;
  {
      return flow {
  
          when (config)
          {
              CONTINUOUS -&gt;
              {
                  //It worked fine when fetchContinuously was ingrained to here and emitted directly to the current flow
                  //And now it keeps on running eternally
                  fetchContinuously().collect { updatedList -&gt;
                      emit(updatedList)
                  }
              }
          }
      }
  }
  
  
  //Note logic of this function is greatly reduced to keep the focus on the problem
  private suspend fun fetchContinuously(): Flow&lt;List&lt;Data&gt;&gt;
  {
      return flow {
          while (currentCoroutineContext().isActive)
          {
  
              val updatedList = fetchDataListOverNetwork().await()
  
              if (updatedList != null)
              {
                  emit(updatedList)
              }
  
              delay(refreshIntervalInMs)
          }
  
          Timber.i(&quot;Context is no longer active - terminating the continuous-fetch coroutine&quot;)
      }
  }
  
  
  private suspend fun fetchDataListOverNetwork(): Deferred&lt;List&lt;Data&gt;?&gt; =
  
      withContext(Dispatchers.IO) {
  
          return@withContext async {
  
              var list: List&lt;Data&gt;? = null
  
              try
              {
                  val response = apiService.getDataList().execute()
  
                  if (response.isSuccessful &amp;&amp; response.body() != null)
                  {
                      list = response.body()!!.list
                  }
                  else
                  {
                      Timber.w(&quot;Failed to fetch data from the network database. Error body: ${response.errorBody()}, Response body: ${response.body()}&quot;)
                  }
              }
              catch (e: Exception)
              {
                  Timber.w(&quot;Exception while trying to fetch data from the network database. Stacktrace: ${e.printStackTrace()}&quot;)
              }
              finally
              {
                  return@async list
              }
              list //IDE is not smart enough to realize we are already returning no matter what inside of the finally block; therefore, this needs to stay here
          }
  
      }
  </code></pre>