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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Do you think random would be meaningfully faster than hashing? I kinda doubt it would make a substantial difference.</p>
<p>Either way the correct approach IMO would be to load-balance with the <a href="https://brooker.co.za/blog/2012/01/17/two-random.html" rel="noopener nofollow ugc">two random choices trick</a> because randomness alone will randomly overload random nodes <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="381605" 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/mesh-capability-based-routing-for-processes-on-the-beam/73925/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-381605" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381605"
                     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="381609" data-post-id="381609">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sleipnir" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sleipnir/120/32563_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sleipnir
                      <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 don’t know, I’d have to measure it, most likely random would be faster. Although that’s not the point of Mesh, mesh is basically a service discovery with the added benefit of being able to activate and monitor the target (process). We’re not talking about a pool, nor endpoints (servers), nor consensus systems; in Mesh we’re only talking about affinity groups. Where knowing the logical Process name, not the PID, nor a registry query, nor anything like that, you are able to send a request, and you are able to do this with “node affinity”, that is, within a larger system (cluster) you can have subsystems and you can logically divide processes among these subsystems.</p>
<p>The reason why random sampling wouldn’t be suitable here is that, in this use case, given that the cluster doesn’t change much, you’ll always be communicating with the same target, and if the cluster eventually changes, it will likely be synchronized at some point.</p>
<p>We will still be working on name collisions, better handling of various issues, the possibility for users to implement their own strategies, and so on… This is just version 0.1.1 of the library, which we are sharing early precisely so we can gather valuable feedback like the kind you gave us.</p>
<p>Without any pretension, I’m sharing the result of one of our benchmarks:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Creating 40,000 actors (10000 per capability)
Time: 2.12s
Throughput: 18827.1 actors/s
Success: 40000/40000 | Failures: 0
Actor distribution per node:
bench@127.0.0.1: 10000 actors
balanced_node_1@127.0.0.1: 10000 actors
balanced_node_2@127.0.0.1: 10000 actors
balanced_node_3@127.0.0.1: 10000 actors

50,000 invocations on existing actors
Time: 3.23s
Throughput: 15484.83 req/s
Success: 50000/50000

Hash ring distribution for 10,000 samples
Expected distribution per node:
bench@127.0.0.1: 2500 actors (25.0%)
balanced_node_1@127.0.0.1: 2500 actors (25.0%)
balanced_node_2@127.0.0.1: 2500 actors (25.0%)
balanced_node_3@127.0.0.1: 2500 actors (25.0%)
Standard deviation: 0.0

FINAL CLUSTER STATE

bench@127.0.0.1:
Status: Online
Processes: 14237
Memory: 124.83 MB
Actors: 10000

balanced_node_1@127.0.0.1:
Status: Online
Processes: 14213
Memory: 101.74 MB
Actors: 10000

balanced_node_2@127.0.0.1:
Status: Online
Processes: 14213
Memory: 104.38 MB
Actors: 10000

balanced_node_3@127.0.0.1:
Status: Online
Processes: 14213
Memory: 103.04 MB
Actors: 10000

Total actors in cluster: 40000
</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="381609" 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/mesh-capability-based-routing-for-processes-on-the-beam/73925/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-381609" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381609"
                     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="381612" data-post-id="381612">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Aloha – thanks for sharing this; it aligns with my own plans.</p>
<p>I opened issue <span class="hashtag-raw">#2</span> and PR <span class="hashtag-raw">#3:</span> <a href="https://github.com/eigr/mesh/pull/3" class="inline-onebox" rel="noopener nofollow ugc">Fix shard lifecycle cleanup, monitor recovery, and capability isolation by nshkrdotcom · Pull Request #3 · eigr/mesh · GitHub</a>.</p>
<p>Full disclosure: I set the investigation criteria and verified the results; Codex and Claude Code handled the investigation, failing tests, fixes, and the issue/PR/commit text.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381612" 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/mesh-capability-based-routing-for-processes-on-the-beam/73925/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-381612" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381612"
                     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="381623" data-post-id="381623">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sleipnir" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sleipnir/120/32563_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sleipnir
                      <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>Hello, thank you very much for your contribution. Available in hex 0.1.3.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381623" 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/mesh-capability-based-routing-for-processes-on-the-beam/73925/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-381623" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381623"
                     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="381625" data-post-id="381625">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="garrison" data-post="12" data-topic="73925">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>Do you think random would be meaningfully faster than hashing? I kinda doubt it would make a substantial difference.</p>
</blockquote>
</aside>
<p>Not meaningfully, but why do hashing by some when there’s no requirement to route things into the same node in the first place?</p>
<aside class="quote no-group" data-username="garrison" data-post="12" data-topic="73925">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>Either way the correct approach IMO would be to load-balance with the <a href="https://brooker.co.za/blog/2012/01/17/two-random.html" rel="noopener nofollow ugc">two random choices trick</a> because randomness alone will randomly overload random nodes <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>
</blockquote>
</aside>
<p>With all respect, this is a hash based routing, based on the key provided by the user. There is a huge chance that some nodes will never be selected if user provides less keys than there are nodes (for example). But even if not, there is guarantee that user provides values which return more or less plain distribution of hashes.</p>
<p>For example, it routes based on <code>request.id</code> which is a string set by user. There is not uniqueness check on it and it can be just hardcoded <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"> (or set to <code>nil</code> by default)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381625" 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/mesh-capability-based-routing-for-processes-on-the-beam/73925/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-381625" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381625"
                     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="381626" data-post-id="381626">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sleipnir" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sleipnir/120/32563_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sleipnir
                      <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>If the user has defined incorrect inputs, they shouldn’t expect guarantees. What we can do is warn them that something is being done incorrectly. We’ll add this validation, and thank you again for the suggestion.</p>
<p>But the goal itself is for them to provide an identity; they do this because they know they’ve defined a process that represents something they expect to happen. It’s not the goal of this library to provide guarantees about the user’s business rules. The user should build that on top of this library, in their own codebase. But as long as they provide a valid identity, they will be directed to the process the user defined.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381626" 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/mesh-capability-based-routing-for-processes-on-the-beam/73925/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-381626" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381626"
                     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="381627" data-post-id="381627">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sleipnir" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sleipnir/120/32563_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sleipnir
                      <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">
								<aside class="quote no-group" data-username="Asd" data-post="16" data-topic="73925">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/a/c68b51/48.png" class="avatar"> Asd:</div>
<blockquote>
<p>Not meaningfully, but why do hashing by some when there’s no requirement to route things into the same node in the first place?</p>
</blockquote>
</aside>
<p>You can implement a custom strategy and implement this behavior if you wish; the most recent documentation explains how to do this.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381627" 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/mesh-capability-based-routing-for-processes-on-the-beam/73925/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-381627" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381627"
                     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="381628" data-post-id="381628">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’ve read the code and here’s my review</p>
<h3><a name="p-381628-tldr-1" class="anchor" href="#p-381628-tldr-1" aria-label="Heading link" rel="nofollow"></a>TLDR</h3>
<p>This is a poor library with a lot of bugs, misleading documentation and poor applicability.</p>
<h3><a name="p-381628-what-does-it-actually-do-2" class="anchor" href="#p-381628-what-does-it-actually-do-2" aria-label="Heading link" rel="nofollow"></a>What does it actually do?</h3>
<p>It essentially does 2 things.</p>
<ul>
<li>You can set some “capabilities” for the node (think of it as of a group name you can assign a current node to) and you can query them<pre data-code-wrap="elixir"><code class="lang-elixir">Mesh.register_capabilities([:game, :chat])
</code></pre>
</li>
<li>You can perform some request on the group, which will pick a node from the group, spawn some (or use existing) GenServer and do the <code>GenServer.call</code> with specified payload<pre data-code-wrap="elixir"><code class="lang-elixir">{:ok, pid, response} = Mesh.call(%Mesh.Request{
  module: MyApp.GameActor,
  id: "player_123",
  payload: %{action: "move"},
  capability: :game
})
</code></pre>
Each node in the group is going to maintain a <code>shard_count</code> of processes per each capability called “actors” in terms of this library (but I call them just shards here) and this request is routed to one of these shards. That means if the node has two capabilities and max shard count is 10, it is going to maintain 20 processes (all of them are lazily initialized).</li>
</ul>
<h2><a name="p-381628-problems-3" class="anchor" href="#p-381628-problems-3" aria-label="Heading link" rel="nofollow"></a>Problems</h2>
<h3><a name="p-381628-setting-capabilities-4" class="anchor" href="#p-381628-setting-capabilities-4" aria-label="Heading link" rel="nofollow"></a>Setting capabilities</h3>
<p>Capabilities is a distributed data, and as all such data it is subject to CAP. Current solution is not qualifying for any of those letters and, putting CAP aside, provides very poor guarantees. If other node can’t start the <code>Mesh</code> and set the capabilities in time, the current node won’t know about it. It uses replication on <code>net_kernel.monitor_nodes</code> events, which just tries to do asynchorous rpc to get the capabilities of other node and share current capabilities with it.</p>
<p>That means that any change to cluster configuration or groups is eventually consistent (at best) and it is quite possible that your request would get routed to the already dead node. If so, this library provides no fallback and you’d just have a dead request</p>
<h3><a name="p-381628-picking-a-node-5" class="anchor" href="#p-381628-picking-a-node-5" aria-label="Heading link" rel="nofollow"></a>Picking a node</h3>
<p>Alright, let’s forget about previous paragraph and imagine that every node has the exactly the same information about the groups (aka “capabilities”).</p>
<p>In pseudo-code it looks like this</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">shard_id = hash(request.id, shard_count)
nodes_in_group = Enum.sort(nodes_for_group(request.node))
node_to_execute_in = Enum.at(nodes_in_group, rem(shard_id, length(nodes_in_group)))
:rpc.call(node_to_execute_in, fn -&gt;
  shard_owner = via(shard_id)  # Yes, shard_id, the same as on the first line
  GenServer.call(shard_owner, {:call, request})
end)

# Where the GenServer.call executes this

pid = start_or_get_shard_process(process, shard_id) # Again, shard_id
response = GenServer.call(pid, request.payload)
{:reply, response, ...}
</code></pre>
<p>And it has many problems. First thing is that routing to the node is not consistent. Second is that shard within node is selected twice, which is a bug.</p>
<p>Then, and it is the most beautiful bug here, <code>shard_id</code> is used as a key for selecting a node in a group and the shard process. That means, that if I have two nodes and 20 shards on each node, only 10 shards on each would receive the request, which is very fun. In general, if I have N nodes, only <code>shards / N</code> amount of shard will receive the request.<br>
Because if I hit the first node on the list of two nodes, that maens that <code>shard_id</code> is dividable by two, and all shards with <code>shard_id</code> not dividable by two won’t receive a request on this node ever.</p>
<p>And for problems which I couldn’t reflect in the pseudo code:</p>
<ul>
<li>Shard processes are created on demand and routed by shard_id. That means if I send a request to a not present shard with Module1 as the implementation, it would start a shard as <code>GenServer.start_link(Module1, ...)</code>, and if I then send a request which would end up in the same shard, but with Module2 passed as the implementation, it would still hit the shard created by the first request, with Module1</li>
<li>If one shard performs a request, which would eventually get routed to the local node, there would be a deadlock. There is no check to ensure that the call ends up in the different shard</li>
</ul>
<h3><a name="p-381628-other-problems-6" class="anchor" href="#p-381628-other-problems-6" aria-label="Heading link" rel="nofollow"></a>Other problems</h3>
<ul>
<li>It creates an <code>ActorTable</code> process on each node which just does nothing.</li>
<li>Misuse of <code>PartitionSupervisor</code></li>
<li><code>Mesh.Cluster.Membership</code> schedules monitoring after 100ms, while it can just do it in handle_continue</li>
<li>This process also syncs shards on every nodeup and nodedown, but it only changes the local shards, so this whole process is unnecessary</li>
<li>If an “actor” dies, it would get restarted by the supervisor, but the ActorTable ets table is going to have the pid of the dead “actor”, resulting in every request hitting the dead process</li>
<li>It uses <code>global</code> for locking on only the current node</li>
</ul>
<h2><a name="p-381628-conclusion-7" class="anchor" href="#p-381628-conclusion-7" aria-label="Heading link" rel="nofollow"></a>Conclusion</h2>
<p>Unclear use-case, bad implementation, misleading documentation.</p>
<p>Same functionality (but without a lot of bugs) can be achieved by using any other process group solution (including bultin <code>global_group</code>, <code>pg</code> and third-party Horde, Swarm, ProcessHub?, syn).</p>
<p>But given that shard processes are expected to be stateless and rounting to be inconsistent, it all boils down to just two lines</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">node = Enum.random(Node.list())
:erpc.call(node, fn -&gt; ... end)
</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="381628" 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/mesh-capability-based-routing-for-processes-on-the-beam/73925/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-381628" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381628"
                     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 #18"></div>
  </section>
</div>
    <div class="postbit" id="381629" data-post-id="381629">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’ve just reread my post, and it sounds a bit toxic. I want to make clear that given that this implementation is poor, it is a good start and the whole idea is not strange, but it is a classic problem which was solved several times by other authors from Elixir community and what you’re doing with <code>Mesh</code> is a good starting point to explore the problem space</p>
<p>My personal recommendation would be to</p>
<ol>
<li>Learn more about distributed systems. I would love to provide some books and resources that I personally find useful, but unfortunately very few of them are in English <img src="https://forum.elixirforum.com/images/emoji/apple/frowning.png?v=15" title=":frowning:" class="emoji" alt=":frowning:" loading="lazy" width="20" height="20"></li>
<li>Take a look at existing implementations, learn about their tradeoffs. For example, <code>Horde</code> library solves the similar problem, but it uses eventually consistent delta-CRDT merkle tree structure to (eventually) maintain the same version of the information about which processes belong to what groups. Other good example is <code>ProcessHub</code> which is, afaik, still in active development phase.</li>
<li>Learn more about consistent hashing algorithms and their applicability. These algorithms are very interesting because there is an exotic mix of finite field algebra and some empirical observations of how distributed systems change their memberships</li>
<li>Dont be afraid to ask questions. You can tag me in any thread or use the personal messages. I also provide mentorship and consulting services. But you can also just create topics on the forum. Discussions about distributed systems are especially welcome here</li>
</ol>
<p>I am looking forward to seeing the new version of Mesh which would use some interesting distributed algorithm. Happy coding <img src="https://forum.elixirforum.com/images/emoji/apple/grinning_cat.png?v=15" title=":grinning_cat:" class="emoji" alt=":grinning_cat:" 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="381629" data-batch-url="/posts/batch_likers">
                        4
                      </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/mesh-capability-based-routing-for-processes-on-the-beam/73925/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-381629" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381629"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="381631" data-post-id="381631">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sleipnir" data-post="1" data-topic="73925">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sleipnir/48/32563_2.png" class="avatar"> sleipnir:</div>
<blockquote>
<p>However, for our specific requirements — especially around <strong>capability-based routing</strong>, <strong>deterministic ownership</strong>, and <strong>very large-scale clustering</strong> — none of them fit exactly what we needed.</p>
</blockquote>
</aside>
<aside class="quote no-group" data-username="sleipnir" data-post="13" data-topic="73925">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sleipnir/48/32563_2.png" class="avatar"> sleipnir:</div>
<blockquote>
<p>We’re not talking about a pool, nor endpoints (servers), nor consensus systems; in Mesh we’re only talking about affinity groups. Where knowing the logical Process name, not the PID, nor a registry query, nor anything like that, you are able to send a request, and you are able to do this with “node affinity”, that is, within a larger system (cluster) you can have subsystems and you can logically divide processes among these subsystems.</p>
</blockquote>
</aside>
<p>Can you articulate your intended usage scenario with a concrete example? Do you want “node affinity” based on performance concerns, ie. hot cache, or physical attributes of the nodes ie, big memory vs small memory, or security/regulation concerns ie. to make private enclaves within a public cloud?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381631" 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/mesh-capability-based-routing-for-processes-on-the-beam/73925/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-381631" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381631"
                     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 #20"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/73925/load_more?page=3">Load more posts</a>
</div></template></turbo-stream>