我的头衔不是很好,因为我发现很难用小片段来解释我想要的东西......所以我会深入尝试!
我正在使用Phoenix Web框架编写Elixir应用程序.
我想要做的是:
该过程不需要返回到Web路由(即其异步)
我知道如何通过使用消息队列(Beanstalk,RabbitMQ,sidekiq)来处理其他语言,并将"作业"交给工作人员,然后编写工作人员来处理队列中的作业.
但是......我知道在Elixir中它默认排队,因为所有内容都被推入"邮箱"(在YouTube视频中看到它:p)
但是我找不到任何合适的代码示例来说明如何让控制器(在phoenix中)产生一个异步进程,该进程将在消息队列中处理.
有没有人知道任何体面的资源,显示我正在寻找什么,或者是否有人有任何代码片段,将给我一个基本的描述如何做到这一点.
谢谢 :)
编辑:
正如评论中所提到的,我已经创建了一个基本教程,介绍如何在Elixir应用程序中启动和运行Poolboy.我希望它对人们有用(并且正确!):)
我正在按照本指南将Ejabberd嵌入Phoenix应用程序(https://blog.process-one.net/embedding-ejabberd-into-an-elixir-phoenix-web-application/),我现在遇到错误它正在运行.
基本上,一切似乎工作正常,直到我导航到" http:// localhost:4000/ejabberd ",此时我收到以下错误:
[error] #PID <0.721.0>运行EjbrdTest.Endpoint终止服务器:localhost:4000(http)请求:GET/ejabberd**(退出)引发异常:**(Plug.Conn.AlreadySentError)响应是已发送(插件)lib/plug/conn.ex:428:Plug.Conn.resp/3(插件)lib/plug/conn.ex:415:Plug.Conn.send_resp/3(ejbrdTest)web/controllers/ejabberd_controller .ex:1:EjbrdTest.EjabberdController.phoenix_controller_pipeline/2(ejbrdTest)lib/phoenix/router.ex:265:EjbrdTest.Router.dispatch/2(ejbrdTest)web/router.ex:1:EjbrdTest.Router.do_call/2 (ejbrdTest)lib/ejbrdTest/endpoint.ex:1:EjbrdTest.Endpoint.phoenix_pipeline/1(ejbrdTest)lib/plug/debugger.ex:90:EjbrdTest.Endpoint."call(overridable 3)"/ 2(ejbrdTest)lib /phoenix/endpoint/render_errors.ex:34:EjbrdTest.Endpoint.call/2(插件)lib/plug/adapters/cowboy/handler.ex:15:Plug.Adapters.Cowboy.Handler.upgrade/4(cowboy)src/cowboy_protocol.erl:442 :: cowboy_protocol .execute/4
而不是用户列表,我在jumbotron中看到了这一点:
在线用户:<%=用户< - @users do%> <%=用户%>
<%end%>
我没有找到任何关于此的内容,任何想法?
谢谢.如果您需要更多信息,请告诉我.
如果我想创建一个模块,其中包含可以在每个模板中访问的函数,并且我可以使用该视图的所有功能(创建标记,使用路由器路径等),那么实现该功能的最佳方法是什么?
简而言之,我如何创建全局视图?
我几乎在所有控制器中都需要以下功能.在Elixir中是否有类似ApplicationController的模块?
我们应该把它们放在哪里?
def redirect_if_unauthorized(conn = %Plug.Conn{assigns: %{authorized: false}}, opts) do
conn
|> put_flash(:error, "You can't access that page!")
|> redirect(to: "/")
|> halt
end
def redirect_if_unauthorized(conn = %Plug.Conn{assigns: %{authorized: true}}, opts), do: conn
Run Code Online (Sandbox Code Playgroud) 对不起,我是Elixir的新手.在构建凤凰应用程序时,mix deps.get失败并出现错误.
% mix deps.get
Could not find Hex, which is needed to build dependency :phoenix
Shall I install Hex? [Yn] y
** (MatchError) no match of right hand side value: {:error, {:ssl, {'no such file or directory', 'ssl.app'}}}
(mix) lib/mix/utils.ex:409: Mix.Utils.read_httpc/1
(mix) lib/mix/utils.ex:354: Mix.Utils.read_path/2
(mix) lib/mix/local.ex:107: Mix.Local.read_path!/2
(mix) lib/mix/local.ex:86: Mix.Local.find_matching_versions_from_signed_csv!/2
(mix) lib/mix/tasks/local.hex.ex:23: Mix.Tasks.Local.Hex.run/1
(mix) lib/mix/dep/loader.ex:140: Mix.Dep.Loader.with_scm_and_app/4
(mix) lib/mix/dep/loader.ex:98: Mix.Dep.Loader.to_dep/3
(elixir) lib/enum.ex:1043: anonymous fn/3 in Enum.map/2
%
Run Code Online (Sandbox Code Playgroud)
erlang和elixir已通过kerl和asdf安装.我的安装日志在这里http://otiai10.hatenablog.com/entry/2016/02/03/154953
envirionment
发生了什么,我该怎么办?
我还在尝试如何处理has_many, through:在Ecto中创建/更新关联的问题.我重新阅读了José关于协会和文档的帖子,但我仍在努力.
我有的是这个:
网络/模型/ dish.ex
defmodule Mp.Dish do
use Mp.Web, :model
schema "dishes" do
# ...
has_many :dish_dietary_prefs, Mp.DishDietaryPref, on_delete: :delete_all,
on_replace: :delete
has_many :dietary_prefs, through: [:dish_dietary_prefs, :dietary_pref]
end
# ...
end
Run Code Online (Sandbox Code Playgroud)
网络/模型/ dietary_pref.ex
defmodule Mp.DietaryPref do
use Mp.Web, :model
schema "dietary_prefs" do
# ...
has_many :dish_dietary_prefs, Mp.DishDietaryPref, on_delete: :delete_all,
on_replace: :delete
has_many :dishes, through: [:dish_dietary_prefs, :dish]
end
# ...
end
Run Code Online (Sandbox Code Playgroud)
网络/模型/ dish_dietary_pref.ex
defmodule Mp.DishDietaryPref do
use Ecto.Schema
schema …Run Code Online (Sandbox Code Playgroud) 我想在一个表中添加一个列,我希望它是一个NOT NULL列.但是我已经有了一些已存在的数据,所以我决定添加列,将所有行更新为某个值并将列修改为NOT NULL.
我尝试了这两个代码:
# solution 1
def up do
alter table(:channels) do
add :type, :integer
Exchat.Repo.update_all("channels", set: [type: 1])
modify :type, :integer, null: false
end
end
# solution 2
def up do
alter table(:channels) do
add :type, :integer
end
Exchat.Repo.update_all("channels", set: [type: 1])
alter table(:channels) do
modify :type, :integer, null: false
end
end
Run Code Online (Sandbox Code Playgroud)
他们两个都没有工作,我得到的错误如下:
23::40::07.514 [info] == Running Exchat.Repo.Migrations.AddTypeToChannels.up/0 forward
23::40::07.541 [debug] UPDATE "channels" AS c0 SET "type" = $1 …Run Code Online (Sandbox Code Playgroud) # mix.exs
defp deps do
[{:phoenix, "~> 1.1.4"},
{:postgrex, ">= 0.0.0"},
{:phoenix_ecto, "~> 3.0.0-rc"},
{:gettext, "~> 0.9"},
...
]
end
Run Code Online (Sandbox Code Playgroud)
安装的ecto版本是 "2.0.0-rc.5"
iex(1)> categories = [%{name: "stackoverflow", url: "stackoverflow.com"}]
iex(2)> App.Repo.insert_all App.Category, categories
** (Postgrex.Error) ERROR (not_null_violation): null value in column "inserted_at" violates not-null constraint
table: categories
column: inserted_at
Failing row contains (1, stackoverflow, stackoverflow.com, null, null).
(ecto) lib/ecto/adapters/sql.ex:176: Ecto.Adapters.SQL.query!/5
(ecto) lib/ecto/adapters/sql.ex:350: Ecto.Adapters.SQL.insert_all/8
(ecto) lib/ecto/repo/schema.ex:42: Ecto.Repo.Schema.do_insert_all/6
iex(2)>
Run Code Online (Sandbox Code Playgroud)
从文档来看,它似乎inserted_at是自动生成的.我应该手动做这部分吗?
schema "categories" do
field :name, :string
field :url, :string
timestamps …Run Code Online (Sandbox Code Playgroud) 我对零停机部署系统感兴趣,该系统不使用Elixir/Erlang热升级(由于代码运行时数据迁移的复杂性).
我听说我可以在将服务器绑定到适配器时使用SO_REUSEPORT选项,这样我就可以运行绑定到同一地址和端口的同一应用程序的两个实例.我的意图是在与运行版本1相同的服务器上部署版本2,启动版本2,然后优雅地停止版本1,这应该允许传入连接自然地开始专门连接到版本2.
无论这是否与我的计划完全一致 - 我的意图是测试这种配置,因为它知道它在不同的操作系统上的行为不同 - 我想知道配置Phoenix执行此操作所需的具体步骤,因为这似乎更低 - 内部的级别配置:gen_tcp.
或者,如果有一种方法可以配置OS或Erlang VM以默认启用此选项的所有连接,那就更好了.
我有一个Elixir伞形应用程序.伞下的应用程序使用Logger.我想为应用程序添加后端(logger_logstash_backend):logger.所以,我需要deps在混合文件中添加它作为函数的依赖项.
在伞形应用程序的最外层混合文件中,deps功能状态的文档:
此处列出的依赖项仅适用于此项目,无法从apps文件夹中的应用程序访问
这意味着我必须将后端模块添加为伞下每个应用程序的依赖项.但是,这样做会导致几个问题:
稍后将单个应用程序移出单独的库变得更加困难.
保护伞下的各个应用程序实际上并不依赖于自定义:logger后端模块.他们没有默认的:console后端.但我想只为prod环境增加一个后端.因此,更多的是跨应用程序问题,我不得不单独为每个应用程序添加依赖项.
你知道更好的策略吗?它是什么?