在Phoenix Framework(Elixir)中实现图库

时间:2015-12-07 11:00:43

标签: elixir phoenix-framework

我正在尝试使用arc实现图库。 我面临以下问题

  1. 无法一次上传多个文件(至AWS S3)
  2. 可以上传小于mb的文件,如果我尝试大文件就会出现超时错误(想知道如何上传大文件)
  3. 从AWS S3显示图像
  4. 上传超过MB的文件时出现的错误是

    [error] Task #PID<0.536.0> started from #PID<0.533.0> terminating
    ** (stop) {:aws_error, {:socket_error, :timeout}}
        (erlcloud) src/erlcloud_s3.erl:911: :erlcloud_s3.s3_request/8
        (erlcloud) src/erlcloud_s3.erl:611: :erlcloud_s3.put_object/6
        (arc) lib/arc/storage/s3.ex:9: Arc.Storage.S3.put/3
        (elixir) lib/task/supervised.ex:74: Task.Supervised.do_apply/2
        (elixir) lib/task/supervised.ex:19: Task.Supervised.async/3
        (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
    Function: #Function<2.64561725/0 in Arc.Actions.Store.async_put_version/3>
        Args: []
    [error] Ranch protocol #PID<0.533.0> (:cowboy_protocol) of listener Pxblog.Endpoint.HTTP terminated
    ** (exit) an exception was raised:
        ** (ErlangError) erlang error: {:aws_error, {:socket_error, :timeout}}
            (erlcloud) src/erlcloud_s3.erl:911: :erlcloud_s3.s3_request/8
            (erlcloud) src/erlcloud_s3.erl:611: :erlcloud_s3.put_object/6
            (arc) lib/arc/storage/s3.ex:9: Arc.Storage.S3.put/3
            (elixir) lib/task/supervised.ex:74: Task.Supervised.do_apply/2
            (elixir) lib/task/supervised.ex:19: Task.Supervised.async/3
            (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
    

    我正在关注arc upload

    以下是控制器的创建功能

    def create(conn, %{"post" => post_params, "images" => images_params}) do
        changeset = Post.changeset(%Post{}, post_params)
    
        case Repo.insert(changeset) do
          {:ok, _post} ->
    
            images = images_params
    
            current_user = %{id: 1}
    
            Enum.count(images, fn(image) -> Image.store({image, current_user}) end)
    
          conn
            |> put_flash(:info, "Post created successfully.")
            |> redirect(to: post_path(conn, :index))
    
          {:error, changeset} ->
            render(conn, "new.html", changeset: changeset)
        end
      end
    

    Arc Library提供了一种方法 MyApp.Avatar.url(),但是当我尝试在show模板中调用它时,例如 MyApp.Avatar.url(@ user.avatar) ,@ user)它表示函数未定义。

2 个答案:

答案 0 :(得分:5)

  

无法一次上传多个文件(至AWS S3)

Elixir因此而拥有并发便利模块!启动多个任务。例如:

images = []

images
|> Enum.map(fn(image) -> async_upload(image, current_user) end)
|> Enum.each(fn(task) -> Task.await(task, 60_000) end)

defp async_upload(image) do
  Task.async(fn ->
    Image.store({image, current_user})
  end)
end
  

可以上传小于mb的文件,如果我尝试大文件就会出现超时错误(想知道如何上传大文件)

Arc中的超时现在是可配置的,可以提升。默认为15秒。

config :arc,
  version_timeout: 15_000 #milliseconds
  

显示来自AWS S3的图像

我不确定这里的问题是什么......但是如果你觉得有什么问题请在Arc上打开一个问题。

免责声明:Arc的作者

答案 1 :(得分:1)

Arc太新了,我认为你最好自己实现所需的所有东西。将命令发送到ImageMagick或用于转换图像的任何内容都没有什么困难,然后您只需使用ex_aws包(或erlcloud,无论您更喜欢哪个)发送AWS S3 API支持的各种请求,实现此操作可能需要的时间少于与arc的争用。

但是回到你的问题,我注意到有这条线:

current_user = %{id: 1}

它只是一张地图,您可能需要使用用户的结构,所以它会是这样的:

current_user = Repo.get(User, 1)

除此之外,正如rorra所说,需要更多代码才能看出可能出现的问题。