<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="350795" data-post-id="350795">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="benwilson512" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/120/1457_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  benwilson512
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Craft GraphQL APIs in Elixir with Absinthe</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>How fast is operation 2 relative to operation 1?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="350795" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-there-an-idiomatic-way-to-write-greedy-streams-in-elixir/68290/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-350795" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="350795"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #21"></div>
  </section>
</div>
    <div class="postbit" id="350812" data-post-id="350812">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lud" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lud/120/14382_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lud
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>It’s shorter <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="350812" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-there-an-idiomatic-way-to-write-greedy-streams-in-elixir/68290/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-350812" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="350812"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #22"></div>
  </section>
</div>
    <div class="postbit" id="350823" data-post-id="350823">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mpope" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mpope
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Would pushing the second computation into a function to make it dependent on the first computation not accomplish the goal?</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">1..1000
|&gt; Stream.map(&amp;perform_compute/1)

def perform_compute(value) do
  value
  |&gt; computation_1()
  |&gt; computation_2()
end
</code></pre>
<p>(I can’t delete this but I realize it does not accomplish what you want as its still serial)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="350823" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-there-an-idiomatic-way-to-write-greedy-streams-in-elixir/68290/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-350823" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="350823"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #23"></div>
  </section>
</div>
    <div class="postbit" id="350836" data-post-id="350836">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="benwilson512" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/120/1457_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  benwilson512
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Craft GraphQL APIs in Elixir with Absinthe</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Right whether this is good or not depends on the ratio of the speed of computation_1 vs computation_2. If computation 2 is 100x faster then this is fine. If it’s only twice as fast then this is less good. Unfortunately all we have to go off of is “It’s shorter” <img src="https://forum.elixirforum.com/images/emoji/apple/person_shrugging.png?v=15" title=":person_shrugging:" class="emoji" alt=":person_shrugging:" loading="lazy" width="20" height="20"> .</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="350836" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-there-an-idiomatic-way-to-write-greedy-streams-in-elixir/68290/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-350836" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="350836"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #24"></div>
  </section>
</div>
    <div class="postbit" id="350846" data-post-id="350846">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mudasobwa" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mudasobwa/120/5298_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mudasobwa
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Cure</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Exactly.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="350846" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-there-an-idiomatic-way-to-write-greedy-streams-in-elixir/68290/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-350846" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="350846"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #25"></div>
  </section>
</div>
    <div class="postbit" id="350849" data-post-id="350849">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lud" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lud/120/14382_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lud
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Sorry I was in a hurry, I should not have posted just that <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>I created this topic to discuss a general common pattern of concurrency between two streams, and not to discuss my specific case.</p>
<p>As I have written, in my case computation 2 is <em>steady</em>, it has constant time. Computation 1 is variable, sometimes it is faster than c2, sometimes it takes more time, way more time.</p>
<p>The sum of all computation 2 is shorter than the sum of all computation 1.</p>
<p>Computation 2 is not instant though, it takes times too.</p>
<p>Say computation 2 is 1 second, computation 1 ranges from 0.5 to 10 seconds.</p>
<p>I was feeling the need to not wait for computation 2 before starting the next computation 1, that is why I asked if a generic pattern or a concurrency handling function is already available.</p>
<p>I have around 500 items, which means I’ll have 500 seconds of computation 2. This is quite long so I wanted to run computations 1 in a greedy fashion, but only one at a time because of high memory consumption.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="350849" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-there-an-idiomatic-way-to-write-greedy-streams-in-elixir/68290/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-350849" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="350849"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #26"></div>
  </section>
</div>
    <div class="postbit" id="350878" data-post-id="350878">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dimitarvp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/120/38664_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dimitarvp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="lud" data-post="27" data-topic="68290">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lud/48/14382_2.png" class="avatar"> lud:</div>
<blockquote>
<p>I created this topic to discuss a general common pattern of concurrency between two streams, and not to discuss my specific case.</p>
</blockquote>
</aside>
<p>Having in mind that streams can have multiple runtime characteristics then the common / general pattern you are looking for either does not exist, or it exists in libraries – something that you are somewhat surprisingly adamant about not using.</p>
<p>Having in mind your use-case and if you want to never lose a single job then <code>Flow</code> might not be your best fit; <code>Oban</code> seems better because:</p>
<ol>
<li>Your first stream’s jobs are not instant (you said 0.5 - 1.0 secs) and it would be a waste to do the calculation but lose it because the runtime crashed or was restarted – f.ex. during deployment.</li>
<li>You don’t want to overload the machine that executes the jobs from the second stream and want them executed one by one – but again, jobs that are “enqueued” should not be lost (IMO anyway) so again, <code>Oban</code> seems like a good fit: you make this second job queue with maximum concurrency of one job at a time and let the system happily chug along until all jobs are completed.</li>
<li>You also get retries in case of intermittent failures.</li>
</ol>
<p>That’s what I would recommend for production usage.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="350878" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-there-an-idiomatic-way-to-write-greedy-streams-in-elixir/68290/28">Post #27</a>
	                </div>
	            </div>
              <div id="likers-container-350878" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="350878"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #27"></div>
  </section>
</div>
    <div class="postbit" id="350890" data-post-id="350890">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mpope" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mpope
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Maybe it’s actually possible to use a single GenServer as a “sink” (and not introduce another library or DATABASE <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> ). This would be a single process and not a process-per element, and would reduce the overhead by quite a bit. Since <code>computation_2</code> isn’t the most intense the GenServer sink can handle both computations and incoming requests. I haven’t tested this yet, I can try it later today or tomorrow but it’d be in the form:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule ComputationSink do
  init(_) do
    %{
      # This is who the final result will be sent to.
      caller: nil,
      inputs: [],
      results: []
    }
  end

  # Here we enqueue more inputs.
  def handle_cast({:put_element, element}, state) do
    {:ok, %{state | inputs: [element | state.inputs]}
  end

  # This is the final call. We make additional calls to compute to process the
  # remaining elements. 
  def handle_call(:get_results, from, state) do
    self() ! :compute
    {:noreply, %{state | caller: from}}
  end

  # If the caller is nil this means that the inputs have not fully been sent, 
  # and that there could be more inputs to compute.
  def handle_info(:compute, %{inputs: [], caller: nil} = state) do
    {:ok, state}
  end

  # Handle the exhausted inputs. 
  # Forward the stored results to the process that initially
  # made the call. "Recursive base case"
  def handle_info(:compute, %{inputs: [], results: results, caller: caller}) when caller !== nil do
    GenServer.reply(caller, results)
    {:ok, %{}}
  end

  # Otherwise apply the computation and self-send a message to continue with processing.
  # This creates a blocking interface with non-blocking internals.
  def handle_info(:compute, state) do
     [current_element | result] = state.inputs
     self() ! :compute
     {:ok, %{state | 
      results: [computation_2(current_element) | state.results], 
      inputs: rest}}
  end
end
</code></pre>
<p>And then we can use this interface here:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">pid_sink = GenServer.start_link(ComputationSink, [])
1..1000
|&gt; Stream.map(&amp;computation_1/)
|&gt; Stream.map(fn element -&gt;
   GenServer.cast(pid_sink, {:put_element, element})
end)
|&gt; Stream.run()

# Blocking call even though the GenServer is still processing elements c:
results = GenServer.call(pid_sink, get_results)
</code></pre>
<p>This is actually my absolute favorite pattern in Erlang / Elixir and I wrote about it here: <a href="https://mattpo.pe/posts/erlang-delayed-send/" class="inline-onebox" rel="noopener nofollow ugc">My Favorite Erlang Pattern</a></p>
<p>EDIT: you could also turn the <code>cast</code> into <code> call</code> and reply slowly or fast depending on the size of the inputs, this will be your backpressure mechanism. You just need to store the pid of the process attempting to enqueue, much like how it is done for the pid of the process storing the result. This would sadly effect the rate of how many computation_1s can run.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="350890" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/is-there-an-idiomatic-way-to-write-greedy-streams-in-elixir/68290/29">Post #28</a>
	                </div>
	            </div>
              <div id="likers-container-350890" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="350890"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>