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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Cachex has <code>get</code>, <code>put</code>, <code>fetch</code>, <code>clear</code>, etc.</p>
<ul>
<li><code>get</code> returns value if it is present in cache, nil if its a cache miss</li>
<li><code>fetch</code> executes fallback function on cache miss.</li>
</ul>
<p>For example - lets have a fallback function which returns same value after delay of 5 seconds.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex(1)&gt; import Cachex.Spec
iex(2)&gt; Cachex.start_link(:my_cache, [ fallback: fallback(default: fn x -&gt; :timer.sleep(5000)
...(2)&gt; x end) ]) 
iex(3)&gt; Cachex.get(:my_cache, 1) #get will return nil as there is no entry
{:ok, nil}
</code></pre>
<p><code>fetch</code> will invoke fallback function when there is a miss - fallback function is executed and value is put into the cache after delay of 5 seconds.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex(4)&gt; Cachex.fetch(:my_cache, 1) # 5 sec delay due to timer.sleep in fallback function
{:commit, 1}
iex(5)&gt; Cachex.get(:my_cache, 1) # get will return value as it exists in cache
{:ok, 1}
</code></pre>
<p>Now  <code>fetch</code> will return value from cache without executing fallback function</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex(6)&gt; Cachex.fetch(:my_cache, 1) # returns immediately, fallback not invoked
{:ok, 1}
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="240711" 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/how-to-write-a-caching-server-in-elixir/45557/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-240711" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="240711"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-solved cat-solved" title="Marked as solution"></div>
  </section>
</div>
    <div class="postbit" id="240795" data-post-id="240795">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="highmountaintea" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/highmountaintea/120/25545_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  highmountaintea
                    <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>Thanks for your detailed explanations. Yes, this will work for the scenario I am describing.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="240795" 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/how-to-write-a-caching-server-in-elixir/45557/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-240795" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="240795"
                     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 #12"></div>
  </section>
</div>
    <div class="postbit" id="240917" data-post-id="240917">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="highmountaintea" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/highmountaintea/120/25545_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  highmountaintea
                    <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>I gave this some more thought, I presume the easiest way is to hold a dictionary of worker processes, each worker process only answers one question. When multiple clients ask for the same question, they’ll queue up on the same worker process, so the same question won’t be asked multiple times. Once the answer arrives, it is cached so all queued and subsequent questions are answered from the cache.</p>
<p>OracleWorker:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule OracleWorker do
  use GenServer
  
  defp query_oracle(question) do
    Process.sleep(30000)
	String.length(question)
  end
  
  def start(question) do
    GenServer.start(__MODULE__, question)
  end
  
  def ask(pid) do
    GenServer.call(pid, :ask)
  end
  
  def init(question) do
    {:ok, {question, nil}}
  end
  
  def handle_call(:ask, caller, state) do
    case state do
	  {question, nil} -&gt;
	    answer = query_oracle(question)
		{:reply, answer, {question, answer}}
	  {question, answer} -&gt;
	    {:reply, answer, state}
	end
  end
end
</code></pre>
<p>OracleServer:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule OracleServer do
  use GenServer
  
  def start do
    GenServer.start(__MODULE__, nil)
  end
  
  defp get_worker(pid, question) do
    GenServer.call(pid, {:get_worker, question})
  end
  
  def ask(pid, question) do
    worker = get_worker(pid, question)
	OracleWorker.ask(worker)
  end
  
  def init(_) do
    {:ok, %{}}
  end
  
  def handle_call({:get_worker, question}, _, cache) do
    case Map.fetch(cache, question) do
	  {:ok, worker} -&gt;
	    {:reply, worker, cache}
	  :error -&gt;
	    {:ok, new_worker} = OracleWorker.start(question)
		{:reply, new_worker, Map.put(cache, question, new_worker)}
	end
  end
end
</code></pre>
<p>This means each question uses one process, so it may use a bit of memory.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="240917" 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/how-to-write-a-caching-server-in-elixir/45557/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-240917" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="240917"
                     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 #13"></div>
  </section>
</div>
    <div class="postbit" id="240918" data-post-id="240918">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="axelson" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/axelson/120/26351_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  axelson
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Scenic Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>For the worker pool portion (since you need to limit the number of workers explicitly) I would probably use a worker pool library. I don’t have direct experience with one but I think two of the most popular are:</p>
<ul>
<li><a href="https://github.com/dashbitco/nimble_pool" class="inline-onebox" rel="nofollow">GitHub - dashbitco/nimble_pool: A tiny resource-pool implementation for Elixir · GitHub</a></li>
<li><a href="https://github.com/devinus/poolboy" class="inline-onebox" rel="nofollow">GitHub - devinus/poolboy: A hunky Erlang worker pool factory · GitHub</a></li>
</ul>
<p>You could also look into Broadway or GenStage (although GenStage is a little low level and a bit tricky to use).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="240918" 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/how-to-write-a-caching-server-in-elixir/45557/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-240918" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="240918"
                     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 #14"></div>
  </section>
</div>
    <div class="postbit" id="240919" data-post-id="240919">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="highmountaintea" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/highmountaintea/120/25545_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  highmountaintea
                    <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>For the solution I mentioned just now, a pool would not work, because I need to keep all worker processes alive to cache the answers.</p>
<p>Each worker caches one answer, so we would lose cached answers if worker processes are allowed to terminate.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="240919" 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/how-to-write-a-caching-server-in-elixir/45557/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-240919" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="240919"
                     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 #15"></div>
  </section>
</div>
    <div class="postbit" id="240923" data-post-id="240923">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="axelson" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/axelson/120/26351_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  axelson
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Scenic Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Ah, I meant using the pool in combination with Cachex and not in the worker processes. Although I now realize that was not very clear. The reason that using a pool is important with Cachex for your use-case is that If you’re using the fallback function with Cachex then you could have more than 5 fallback functions running at the same time if you’re trying to fetch more than 5 keys at the same time. By using a pool you can explicitly limit the number of fallback functions that are currently accessing the oracle on the moon.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="240923" 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/how-to-write-a-caching-server-in-elixir/45557/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-240923" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="240923"
                     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 #16"></div>
  </section>
</div>
    <div class="postbit" id="240927" data-post-id="240927">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="highmountaintea" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/highmountaintea/120/25545_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  highmountaintea
                    <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>Ah, got it. Thanks for the tip. I will keep it in mind when I use Cachex.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="240927" 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/how-to-write-a-caching-server-in-elixir/45557/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-240927" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="240927"
                     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>