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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The MapSet is referred to as <code>tasks</code>.</p>
<p>Using the <code>MyWorker</code> module might look as follows:</p>
<p><em>in a supervisor, possibly the root application supervisor</em></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">children = [
  ...
  worker(MyWorker, [])
]
</code></pre>
<p><em>adding user tasks</em></p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># adding a task with user ID 1
MyWorker.add(1)

# adding a second task with user ID 2
MyWorker.add(2)
</code></pre>
<p><em>removing a user task</em></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">MyWorker.remove(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="31281" 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/periodic-tasks-in-a-single-genserver-not-everything-yet-makes-sense/4813/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-31281" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="31281"
                     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 #11"></div>
  </section>
</div>
    <div class="postbit" id="31288" data-post-id="31288">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="nezzart" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  nezzart
                    <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>Where is an instance of MapSet.new which is “tasks” actually stored?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="31288" 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/periodic-tasks-in-a-single-genserver-not-everything-yet-makes-sense/4813/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-31288" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="31288"
                     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="31304" data-post-id="31304">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="net" data-post="2" data-topic="4813">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/net/48/429_2.png" class="avatar"> net:</div>
<blockquote>
<pre data-code-wrap="elixir"><code class="lang-elixir">def init(_) do
    tick()

    # Here we use a MapSet as it will reject duplicate items.
    # If you wish to store more data with a task than just a user ID,
    # use a Map instead.
    {:ok, MapSet.new}
  end
</code></pre>
</blockquote>
</aside>
<p>He already showed this code here, it is at the bottom of the init call.  ^.^</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="31304" 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/periodic-tasks-in-a-single-genserver-not-everything-yet-makes-sense/4813/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-31304" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="31304"
                     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="31311" data-post-id="31311">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="nezzart" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  nezzart
                    <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>That’s not where it’s stored, that’s where it’s created.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="31311" 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/periodic-tasks-in-a-single-genserver-not-everything-yet-makes-sense/4813/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-31311" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="31311"
                     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="31317" data-post-id="31317">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="nezzart" data-post="15" data-topic="4813" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/n/e36b37/48.png" class="avatar"> nezzart:</div>
<blockquote>
<p>That’s not where it’s stored, that’s where it’s created.</p>
</blockquote>
</aside>
<p>And also where it is stored, as that is the returned state that is then threaded through all other calls.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="31317" 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/periodic-tasks-in-a-single-genserver-not-everything-yet-makes-sense/4813/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-31317" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="31317"
                     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="31318" data-post-id="31318">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="nezzart" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  nezzart
                    <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>Does GenServer handle it under the hood? Where in the documentation is that described?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="31318" 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/periodic-tasks-in-a-single-genserver-not-everything-yet-makes-sense/4813/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-31318" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="31318"
                     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="31319" data-post-id="31319">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group quote-modified" data-username="nezzart" data-post="17" data-topic="4813">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/n/e36b37/48.png" class="avatar"> nezzart:</div>
<blockquote>
<p>Does GenServer manage it? Where is that described?</p>
</blockquote>
</aside>
<p>Yes, and it is described in the GenServer documentation.  <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>Imagine genserver implemented this way in pseudo-code:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def start_link(user_module, args) do
  {:ok, spawn_link(fn -&gt; gen_server_init(user_module, args) end)}
end

def gen_server_init(user_module, args) do
  {:ok, state} = user_module.init(args)
  gen_server_loop(user_module, state)
end

def gen_server_loop(user_module, state) do
  receive do
    {:__special_genserver_cast__, msg} -&gt;
      {:noreply, newstate} = user_module.handle_cast(msg, state)
      gen_server_loop(user_module, newstate)
    {:__special_genserver_call__, msg, from} -&gt;
      {:reply, outmsg, newstate} = user_module.handle_call(msg, from, state)
      send(from, outmsg)
      gen_server_loop(user_module, newstate)
    unknown_msg -&gt;
      {:noreply, newstate} = user_module.handle_info(unknown_msg, state)
      gen_server_loop(user_module, newstate)
  end
end
</code></pre>
<p>And so forth, but with significantly more error checking and cases and such.  GenServer is just an infinite receiving loop passing the state from iteration to iteration.  <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="31319" 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/periodic-tasks-in-a-single-genserver-not-everything-yet-makes-sense/4813/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-31319" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="31319"
                     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 #17"></div>
  </section>
</div>
    <div class="postbit" id="31663" data-post-id="31663">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I would recommend you to have a look at the <a href="https://hexdocs.pm/elixir/Registry.html" rel="noopener nofollow ugc">Registry</a> module.</p>
<p>First, some considerations:</p>
<ol>
<li>Say you run one <code>GenServer</code> per user;</li>
<li>And you have a rescheduler as a separate <code>GenServer</code> process.</li>
</ol>
<p>Tackling the first part, which involves associating a user’s id with a process, start one if one is not running and keeping a list of executing processes based on the user’s name, can be done using the following construct:</p>
<pre><code>defmodule MyWorker do
  use GenServer

  @doc """
  Should be called before `start_worker`.
  """
  def start_link() do
    Registry.start_link(:unique, __MODULE__)
  end

  @doc """
  Starts a worker process for a given `user` to handle the given `task`.
  """
  def maybe_start_worker(user, task) do
    case Registry.lookup(__MODULE__, user) do
      [{pid, _value}] -&gt;
        {:ok, pid}  # do nothing, already running
      [] -&gt;
        name = {:via, Registry, {__MODULE__, user}}
        GenServer.start_link(__MODULE__, task, name: name)
    end
  end

  def init(task) do
    self() |&gt; Process.send_after(:process_task, 0) 
    {:ok, task}
  end

  def handle_info(:process_task, task) do
    # do something with the task
    access_external_service(task)

    # finishes the process, nothing else to do for the moment
    {:stop, :normal, task}
  end

  defp access_external_service(task) do
    # a request to an external web server
  end
end
</code></pre>
<p>Assuming the above, then now you could create another process to re-run the worker process every 30 seconds. This another process can hold a simple <code>Map</code> where the key is the user’s id and the value is the task. Just call <code>MyScheduler.add_item/2</code> when the user clicks on the button, followed by <code>MyWorker.start_worker/2</code> if you want to process the task immediately, otherwise, the worker will be executed 30 seconds later by the scheduler.</p>
<pre><code>defmodule MyScheduler do
  use GenServer

  def start_link() do
    GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
  end

  def add_item(user, task) do
    GenServer.call(__MODULE__, {:add_item, user, task})
  end

  def remove_item(user) do
    GenServer.call(__MODULE__, {:remove_item, user})
  end

  def init(map), do: {:ok, map}

  def handle_info({:reschedule, user, task}, map) do
    MyWorker.maybe_start_worker(user, task)
    timer = self() |&gt; Process.send_after({:reschedule, user, task}, 30_000)  # reschedule
    {:noreply, %{map | user =&gt; {task, timer}}}
  end

  def handle_call({:add_item, user, task}, map) do
    timer = self() |&gt; Process.send_after({:reschedule, user, task}, 30_000)
    {:reply, :ok, map |&gt; Map.put(user, {task, timer})
  end

  def handle_call({:remove_item, user}, map) do
    map =
      map |&gt; Map.get_and_update(user, fn {_task, timer} -&gt;
        timer |&gt; Process.cancel_timer()
        :pop
      end)
    {:reply, :ok, map}
  end
end
</code></pre>
<p>With the above:</p>
<ol>
<li>Say your process takes more than 30 seconds to execute; suppose 45 seconds. Then, when the scheduler gets the first timer event, it won’t start a new process at that moment; as it keeps retrying every 30 seconds, the task will be executed in the next try, after 60 seconds.</li>
<li>In order to stop rescheduling, execute <code>MyScheduler.remove_item/1</code> for the same user ID you used in <code>MyScheduler.add_item/2</code>.</li>
</ol> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="31663" 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/periodic-tasks-in-a-single-genserver-not-everything-yet-makes-sense/4813/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-31663" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="31663"
                     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>