Using Elixir Dynamic Supervisors
转自: https://blog.smartlogic.io/elixir-dynamic-supervisors/
I have been working on my side project Grapevine, a community site for text based multiplayer games (MUDs.) The existing games primarily have a telnet interface for playing. This generally involves using a local client or hoping the game provides a web client for you. So I've been working on a general purpose client that any game can use. You can see it in action for my game MidMUD.
This involves a new web client that uses Phoenix Channels to spin up a backing :gen_tcp process. This process is started inside of a DynamicSupervisor, a new feature introduced in Elixir 1.6. We place the process inside of the supervisor to keep the process alive across page reloads. Lets see how it works!
Basic Flow

When a new web client starts they join a channel named play:client. The channel ensures that the game they are trying to connect to exists and starts the backing process.
{:ok, pid} = WebClient.connect(socket.assigns.user,
game_id: socket.assigns.game.id,
host: connection.host,
port: connection.port,
channel_pid: socket.channel_pid
)
This Client process starts itself inside of a DynamicSupervisor as a transientprocess and saves the calling channel PID in order to forward any received data to the front end. This uses the DynamicSupervisor.start_child/2 function.
def start_client(callback_module, opts) do
spec = {Client, [module: callback_module] ++ opts}
DynamicSupervisor.start_child(__MODULE__, spec)
end
Once the Client process is alive it parses the telnet stream and forwards any text directly to the web front end.
Handling Page Reloads
The Client process is globally registered with the user's ID and the game's ID as part of the name, {:webclient, {1, 1}}. With this, we can check :global to see if the process already exists before starting a new process. If the process exists we overtake the Client process with our new channel.
def connect(user, opts) do
case :global.whereis_name(pid(user, opts)) do
:undefined ->
ClientSupervisor.start_client(__MODULE__, opts ++ [name: {:global, pid(user, opts)}])
pid ->
set_channel(pid, opts[:channel_pid])
{:ok, pid}
end
end
set_channel/2 sends a message to the process which sets the internal channel_pid state for forwarding text to the web client.
Conclusion
With this setup I'm able to have a place to supervise Client processes and allow for session "stickiness" on page reloads. The DynamicSupervisor will delete the child_spec of the Client process after it terminates with a :normal reason. Otherwise the process will be restarted allowing for minor hiccups in the network.
All of this code is open source on GitHub, check out the Grapevine repo. I also worked on this during my Elixir live coding stream. I'll be back doing more live coding on that channel every Monday from 12PM-1PM Eastern.
Using Elixir Dynamic Supervisors的更多相关文章
- [Erlang 0108] Elixir 入门
Erlang Resources里面关于Elixir的资料越来越多,加上Joe Armstrong的这篇文章,对Elixir的兴趣也越来越浓厚,投入零散时间学习了一下.零零散散,测试代码写了一些,Ev ...
- 基于Erlang VM的函数式编程语言Elixir
Elixir官网:http://elixir-lang.org/ Elixir是一种函数式动态语言,用于构建可伸缩.易维护的应用程序. Elixir是基于Erlang VM的,其广为人知的特点是运行低 ...
- Elixir游戏服设计四
上章说到我们要引入syn https://github.com/ostinelli/syn/ 看过文档,它并没有直接提供{via, Module, Name} 相关的方法.我们需要封装一下. Name ...
- Elixir游戏服设计三
玩家进程用gen_server来建模,我不直接使用 use GenServer, 而是使用exactor,该库可以去掉反锁的接口定义. 我们新建一个 player_server_manager app ...
- Connecting Elixir Nodes with libcluster, locally and on Kubernetes
转自:https://www.poeticoding.com/connecting-elixir-nodes-with-libcluster-locally-and-on-kubernetes/ Tr ...
- Install Erlang and Elixir in CentOS 7
In this tutorial, we will be discussing about how to install Erlang and Elixir in CentOS 7 minimal s ...
- PatentTips - Systems, methods, and devices for dynamic resource monitoring and allocation in a cluster system
BACKGROUND 1. Field The embodiments of the disclosure generally relate to computer clusters, and m ...
- var和dynamic的区别
1.var 1.均是声明动态类型的变量. 2.在编译阶段已经确定类型,在初始化的时候必须提供初始化的值. 3.无法作为方法参数类型,也无法作为返回值类型. 2.dynamic 1.均是声明动态类型的变 ...
- 遍历dynamic的方式
一.遍历ExpandoObject /// <summary> /// 遍历ExpandoObject /// </summary> [TestMethod] public v ...
随机推荐
- Cracking The Coding Interview 1.3
//原文: // // Design an algorithm and write code to remove the duplicate characters in a string withou ...
- Linux系统管理常用命令用法总结(2)
1.free指令会显示内存的使用情况,包括实体内存,虚拟的交换文件内存,共享内存区段,以及系统核心使用的缓冲区等. 语法:free [-bkmotV][-s <间隔秒数>] 参数说明: - ...
- js 将文本转换为数据 string number
<span class="Span" > <p>123.81</p> <a> dejiw</a> </span&g ...
- Excel日常操作
1.固定表头 视图+冻结窗口+选择 2.下拉列表 数据+数据验证+序列+来源 筛选值也可是函数,函数值区间可以选择,然后隐藏该列数据即可 使用函数: 如果需要函数的值其他列也使用类似函数则拖动同样格式 ...
- springboot学习章节代码-spring基础
1.DI package com.zhen.highlights_spring4.ch1.di; import org.springframework.stereotype.Service; /** ...
- Linux文件系统命令 split
命令:split 功能:将文件按照一定的规则进行切割 用法:-l 表示按照行数进行切割. -b 表示按照字节进行切割,切割后的文件名为自己定义的文件名+aa,ab,ac类似的后缀. eg: 按照行数进 ...
- L314 单音节词读音规则(二)-元音字母发音规则
1 单个元音发音尽量拖音一下(2S),发音会饱满一些. 2开音节: 辅音(辅组)(没有)+元音+辅音+e 的单词其中:元音发字母本身音,辅音字母不为r , 字母e不发音. 相对开音节:第一个元音都发字 ...
- Linux:NFS配置
NFS配置 1.创建分享的文件:touch /var/www/html/aa.txt2.查看是否安装NFS:rpm -qa|grep nfs3.查看IP地址:ifconfig4.配置NFS:vi /e ...
- apache rewrite 规则
啥是虚拟主机呢?就是说把你自己的本地的开发的机子变成一个虚拟域名,比如:你在开发pptv下面的一个项目 127.0.0.1/pptv_trunk,你想把自己的机器域名变成www.pptv.com.那么 ...
- Jmeter监听tomcat
配置cd /usr/local/tomcat/conf/tomcat-users.xml