小编ska*_*tek的帖子

如何直观地描述gen_server?

免责声明:作者是OTP的新手,具有Erlang语法,过程和消息的一些基本知识.

我试图理解Erlang中的行为概念,但是我头脑中的许多问题使我无法理解像gen_server这样的行为的整个原则.

好的,gen_server的官方文档显示了一个很好的服务器图和三个与查询和回复箭头相关的客户端:http: //www.erlang.org/doc/design_principles/gen_server_concepts.html

但每次我试图进一步理解这个概念时,我都会陷入困境.

有很多概念我无法在脑海中构建成一个更大的概念:

  • 行为实施;
  • 行为容器;
  • 行为界面;
  • 回调模块;
  • 回调函数;
  • API函数.

我使用以下资源:

我仍然处于状态"我们在一个模块中调用一个函数,这个函数调用另一个函数,该函数创建一个进程...卡住"

有没有办法在图表中描述gen_server的概念?如何在视觉上显示客户端和服务器之间的交互流?(帮助不那么聪明的新人在视觉上理解这个概念)

例如,像这里:http://support.novell.com/techcenter/articles/img/dnd2003080506.gif

UPD:我试图绘制我自己的图表,但我仍然没有达到图中任何连接器的目的:http://postimage.org/image/qe215ric/full/

UPD2:这与我希望看到的类似:http://cryptoanarchy.org/wiki/Worker_patterns(模型).但是,它没有显示模块,功能和过程之间的交互.

erlang gen-server

7
推荐指数
1
解决办法
982
查看次数

在Erlang中用于Dijkstra算法的数据结构是什么?

免责声明:作者是Erlang的新手.

想象一下,我们有一个由1M个节点组成的图形,每个节点有0-4个邻居(边缘从每个节点发出到那些邻居,因此图形是定向和连接的).

这是我选择的数据结构:

为了存储图形,我使用了基于ETS表的有向图.这允许快速(O(1))访问节点的邻居.

对于未访问节点的列表,我使用gb_sets:take_smallest(节点已经排序,并且在获取后同时删除).

对于前趋列表,我使用dict结构,它允许以下列方式存储前驱:{Node1,Node1_predecessor},{Node2,Node2_predecessor}.

对于访问节点列表,我使用一个简单的列表.

问题:

  1. 当我尝试在digraph结构和Unvisited_nodes结构中更新节点的权重时,代码变得非常难以阅读和维护.将一个"对象"与需要同时在两个数据结构中更新的"字段"保持在一起似乎不是正确的方法.这样做的正确方法是什么?
  2. 同样的问题是关于前辈名单.我应该在哪里存储节点"对象"的前任"字段"?也许在Graph(有向图结构)?
  3. 也许我应该重新考虑整个Dijkstra算法的过程和消息而不是对象(节点和边)及其字段(权重)?

UPD:

以下是基于Antonakos建议的代码:

dijkstra(Graph,Start_node_name) ->

    io:format("dijkstra/2: start~n"),

    Paths = dict:new(),
    io:format("dijkstra/2: initialized empty Paths~n"),

    Unvisited = gb_sets:new(),
    io:format("dijkstra/2: initialized empty Unvisited nodes priority queue~n"),

    Unvisited_nodes = gb_sets:insert({0,Start_node_name,root},Unvisited),
    io:format("dijkstra/2: Added start node ~w with the weight 0 to the Unvisited nodes: ~w~n", [Start_node_name, Unvisited_nodes]),

    Paths_updated = loop_through_nodes(Graph,Paths,Unvisited_nodes),
    io:format("dijkstra/2: Finished searching for shortest paths: ~w~n", [Paths_updated]).




loop_through_nodes(Graph,Paths,Unvisited_nodes) ->
    %% We need this condition to stop looping through the Unvisited nodes if it …
Run Code Online (Sandbox Code Playgroud)

erlang directed-graph dijkstra shortest-path

6
推荐指数
1
解决办法
2374
查看次数

在Erlang中查找有向循环图中一个顶点的所有可能路径

我想实现一个函数,该函数在有向循环图G中找到来自源顶点V的所有可能顶点的所有可能路径.

性能现在没关系,我只是想了解算法.我已经阅读了深度优先搜索算法的定义,但我并不完全理解该怎么做.

我没有在这里提供任何完整的代码,因为我不知道如何:

  • 存储结果(连同A-> B-> C->我们还应该存储A-> B和A-> B-> C);
  • 代表图(有向图?元组列表?);
  • 要使用多少递归(处理每个相邻的顶点?).

如何在Erlang中的有向循环图中找到形成一个给定源顶点的所有可能路径?

UPD:基于到目前为止的答案,我必须重新定义图形定义:它是一个非非循环图形.我知道如果我的递归函数遇到一个循环,它就是一个无限循环.为了避免这种情况,我可以检查当前顶点是否在结果路径的列表中 - 如果是,我停止遍历并返回路径.


UPD2:感谢发人深省的评论!是的,我需要找到所有简单路径,这些路径没有从一个源顶点到所有其他源的循环.

在这样的图表中:

非非循环图

使用源顶点A算法应找到以下路径:

  • A,B
  • A,B,C
  • A B C D
  • 广告
  • A,d,C
  • A,d,C,B

下面的代码完成了这项工作,但是对于具有更多20个顶点的图形它是不可用的(我猜它是递归错误的东西 - 占用太多内存,永远不会结束):

dfs(Graph,Source) ->
    ?DBG("Started to traverse graph~n", []),
            Neighbours = digraph:out_neighbours(Graph,Source),
    ?DBG("Entering recursion for source vertex ~w~n", [Source]),
            dfs(Neighbours,[Source],[],Graph,Source),
ok.


dfs([],Paths,Result,_Graph,Source) ->
    ?DBG("There are no more neighbours left for vertex ~w~n", [Source]),
    Result;

dfs([Neighbour|Other_neighbours],Paths,Result,Graph,Source) ->
    ?DBG("///The neighbour to check is ~w, other neighbours are: ~w~n",[Neighbour,Other_neighbours]),
    ?DBG("***Current result: ~w~n",[Result]),
    New_result = …
Run Code Online (Sandbox Code Playgroud)

erlang graph directed-graph depth-first-search

6
推荐指数
1
解决办法
4535
查看次数

使用开源3D引擎从Openstreetmap数据渲染地图?

从Openstreetmap数据渲染3D地图可能非常麻烦.

但是,如果要求的要求低于渲染世界上任何城市的3D要求呢?

如果我只需要渲染某个受特定边界限制的城市怎么办?不应该渲染很多多边形,特别是如果我选择只渲染那些在屏幕上实际看到的建筑物和道路(我听说这种技术用于游戏开发).

我希望能够实现这样的目标,但是对于具有近似高度且没有纹理的建筑物来说,只需要简单的盒子就可以了.所以,基本上我只需要一个基于OSM的道路网络和用3D表示建筑物的简单框.

所以,计划可能如下:

  • 将OSM数据提取到.osm文件中;
  • 将"高度"数据添加到此文件中的每个建筑物(手动);
  • 使用某种3D引擎从.osm文件(需要自定义解析器)渲染地图的3D视图.

这个计划可行吗?是否有任何开源3D引擎可以使用/自定义从.osm文件渲染OSM地图?是否存在可以[可能]自定义以呈现OSM地图的任何Linux兼容(OpenGL?)3D引擎?

3d openstreetmap

6
推荐指数
1
解决办法
8097
查看次数

Erlang/OTP:RESTful 应用程序中的授权/身份验证

我正在设计一个 Erlang/OTP 应用程序,它将通过 RESTful API 公开其服务 (SOA)。

构成后端的服务将是数据库服务、价格计算服务等。

客户端可以有多种类型:Web 客户端、移动客户端、Asterisk 服务器客户端(需要在数据库服务中查找用户记录),甚至是我不打算拥有且还不了解的客户端。客户端将以不同的方式使用 RESTful API:有些将使用所有服务,有些将仅使用部分服务(SOA 方式)。

我主要关心的是身份验证/授权。

RESTful Web 应用程序

我无法使用 Ruby on Rails 的内置身份验证/授权,因为 Web 客户端只是通过 RESTful API 使用应用程序的许多可能客户端中的一个客户端。

所以,我的问题是:

  • 对于预计与许多不同客户端一起使用的典型 RESTful Web 应用程序,身份验证/授权的一般概念是什么?
  • RESTful Web 应用程序中最实用的授权/身份验证软件设计模式是什么?
  • 您可以推荐哪些 Erlang/OTP 开源软件库来为此类应用程序实现身份验证/授权?

rest erlang authorization restful-authentication erlang-otp

6
推荐指数
1
解决办法
5927
查看次数

Erlang容错应用程序:CAP的PA或CA?

我已经问了一个问题,关于一个简单的容错软实时网络比萨饼店交付应用.

在此输入图像描述

我在那里得到了非常好的评论和答案,但我不同意这是一个真正的网络服务.它不仅仅是一种网络服务,它更像是一个实时系统来接受客户的订单,控制这些订单的调度并控制实时交付这些订单的车辆.

此外,与"真正的"网络服务不同,这个系统不是为了拥有许多用户 - 只有少数调度员(电话运营商)和一些将使用它的交付驱动程序(因为现在我没有要求提供直接访问)为实际客户提供服务;只有调度员和交付司机才能直接访问).

因此这个问题有点笼统.

我发现,为了做出正确的选择,为我所要做的这个应用程序的第一件事NoSQL数据存储选项之间做出选择CA,PACP根据CAP定理.

现在,使用Erlang构建Web应用程序的书称"虽然它[Mnesia]不是SQL数据库,但它是一个像SQL数据库一样的CA数据库.它不会处理网络分区".同一本书说CouchDB数据库是一个PA数据库.

考虑到这一点,我认为我需要对我的应用程序做的第一件事是确定"容错"术语对CAP的意义.

我的简单要求是使应用程序24/7(R1)可用.另一个是没有必要扩展,应用程序将拥有非常适量的用户(可能无法拥有数千个调度程序)(R2).

现在,R1是否要求应​​用程序提供一致性,可用性和分区容差以及具有哪些优先级?

什么类型的数据存储选项将更好地处理以下问题:

  1. 为调度员(接受客户电话和使用CRM的人)提供24/7可用性,以查找客户记录并将订单输入系统;
  2. 查看当前正在进行的服务订单及其状态(放置,烘焙,发送,交付,交付)实时;
  3. 实时跟踪所有工作车辆的位置及其有效载荷;
  4. 在系统崩溃或网络崩溃后恢复系统的任何部分以继续提供1,2和3;

总结一下:什么样的数据存储(CA,PA或CP)将更好地适应上述系统?什么样的数据存储能更好地满足R1要求?

erlang couchdb mnesia erlang-otp cap

6
推荐指数
1
解决办法
808
查看次数

一种通用的跨平台方式(移动),向用户显示警报

我有一项任务是创建一个客户端应用程序,该应用程序可以向用户显示通知被发现的概率很高的通知.

该应用程序应该适用于Android(2.0 +)/ iOS/WP.

以下是用例:

  1. 用户启动应用程序并执行一些操作.然后他切换到主屏幕/另一个应用程序.
  2. 对Action的响应使应用程序发出通知.用户注意到通知,而不管他此刻在他的移动设备上使用了什么另一个应用程序(或主屏幕).

不要求应用程序是本机应用程序或基于Web浏览器的移动应用程序.通知可能是设备上的声音或振动,但我知道从浏览器中访问振动仍然很棘手.

以下是迄今为止制作通用声音/振动通知机制的研究结果:

  • 似乎让移动设备从浏览器振动只能在移动Firefox中运行(没有iOS,没有WP);
  • audiohtml5标签的支持仍然是实验性的,它不适用于每个浏览器/设备;
  • 此示例中的声音警报仅适用于移动Firefox(要求插件播放mp3声音),Android浏览器保持静音.

所以,问题是:

有没有办法强迫移动设备用户(Android 2.0 +/iOS/WP)查看来自移动应用程序的通知?唯一的方法是为每个移动平台编写本机应用程序吗?

notifications alert cross-browser push-notification vibration

6
推荐指数
1
解决办法
288
查看次数

Erlang/OTP持续部署简介

注意:这是我之前关于类似主题的问题的进化延续.

我一直在寻找有关部署和更新Erlang/OTP版本(一组应用程序)的"最佳实践",但是我找不到任何直接的解决方案描述,但只能找到一些"相关信息":

http://blog.equanimity.nl/blog/2013/06/04/continuous-integration-for-erlang-with-travis-ci/

https://www.youtube.com/watch?v=G0eBDWigORY

https://www.youtube.com/watch?v=0ZGHzI9F5YE

我所说的"直接解决方案"是对以下问题的回答:

鉴于生产Erlang/OTP集群的Erlang/OTP版本在几个Erlang节点上运行,这些节点充当高可用性(24/7)REST API,如何定期将新代码推送到该生产集群?有没有最好的做法来做那些像git push heroku master Heroku一样简单的做法?如果没有,在生产中连续重新部署和Erlang/OTP软件的最简单方法是什么?

我已经阅读了"Erlang/OTP in Action"一书来了解如何处理Erlang/OTP应用程序和发行版,在我看来,简单的软件升级并不那么容易.使用reltool时必须生成存档,将该存档移动到生产机器(scp?),在那里解压缩,运行Erlang shell并将新模块加载到Erlang VM中.

另外,"Learn You Some Erlang"一书中指出了以下内容:

"...如果你可以避免整个过程(从现在开始称为relup)并通过重新启动VM并启动新应用程序来进行简单的滚动升级,我建议你这样做."

"有人说爱立信的部门使用relups会花费尽可能多的时间测试它们,就像测试应用程序本身一样."

此外,这是另一个建议,以避免生产中的Erlang版本的热交换.

如果这是真的,那么我没有看到'Erlang热代码升级'的任何用处,因为我必须在每次升级时重启VM.这让我不知道在生产中定期部署Erlang/OTP新代码的强大且经过测试的方法.

PS关于我的软件要求的一些注释.

  • 我正在编写一组没有任何会话的API入口点,因此在软件更新期间无需维护会话.
  • 没有必要分发Erlang/OTP版本,我正在使用内部定制产品.

erlang continuous-integration yaws high-availability erlang-otp

6
推荐指数
1
解决办法
1004
查看次数

如何在Erlang中优化数千条消息的接收循环?

在编程Erlang书的"编程多核CPU"一章中,Joe Armstrong给出了一个很好的并行化map函数的例子:

pmap(F, L) ->
    S = self(),
    %% make_ref() returns a unique reference
    %% we'll match on this later
    Ref = erlang:make_ref(),
    Pids = map(fun(I) ->
        spawn(fun() -> do_f(S, Ref, F, I) end)
    end, L),
    %% gather the results
    gather(Pids, Ref).

do_f(Parent, Ref, F, I) ->
    Parent ! {self(), Ref, (catch F(I))}.

gather([Pid|T], Ref) ->
    receive
        {Pid, Ref, Ret} -> [Ret|gather(T, Ref)]
    end;

gather([], _) ->
    [].
Run Code Online (Sandbox Code Playgroud)

它工作得很好,但我相信它有一个瓶颈,导致它在100,000多个元素的列表上工作得非常慢.

gather()执行该功能时,它开始匹配列表中的第Pid一个Pids与主进程邮箱中的消息.但是如果邮箱中最旧的邮件不是来自这个Pid呢?然后它会尝试所有其他消息,直到找到匹配项.话虽如此,有一定的可能性,在执行gather()函数时,我们必须循环遍历所有邮箱消息,以找到与Pid …

parallel-processing erlang

5
推荐指数
1
解决办法
1205
查看次数

通过端口从 Erlang 调用 C 函数的最快、最简单的方法是什么?

Francesco Cesarini 的《Erlang 编程》一书提供了一个很好且易于上手的示例,将 Erlang 连接到 Ruby(通过端口实现):

module(test.erl).
compile(export_all).    

test() ->
    Cmd = "ruby echoFac.rb",
    Port = open_port({spawn, Cmd}, [{packet, 4}, use_stdio, exit_status, binary]),
    Payload = term_to_binary({fac, list_to_binary(integer_to_list(23))}),
    port_command(Port, Payload),
    receive
     {Port, {data, Data}} ->
      {result, Text} = binary_to_term(Data),
      Blah = binary_to_list(Text),
      io:format("~p~n", [Blah])
    end.
Run Code Online (Sandbox Code Playgroud)

但是,本示例中使用的 Ruby 代码使用 Erlictricity 库,该库为程序员完成所有低级操作:

require 'rubygems'
require 'erlectricity'
require 'stringio'
def fac n
if (n<=0) then 1 else n*(fac (n-1)) end
end
receive do |f|
f.when(:fac, String) do |text|
n = text.to_i
f.send!(:result, "#{n}!=#{(fac …
Run Code Online (Sandbox Code Playgroud)

c c++ erlang erlang-ports

5
推荐指数
1
解决办法
1573
查看次数