Why should I use "Process.sleep/1" with a Live Form Component?

I’m currently learning LiveView with the really good Programming Phoenix Liveview book by Bruce A. Tate and Sophie DeBenedetto.

So now I’m in the chapter about file uploads. We used phx.gen.live to generate a catalog products CRUD then in the live modal FormComponent we add a feature to allow a picture upload when saving a new product or editing an existing one.

Apart from a consume_uploaded_entry/3 function that returns a path instead of a {:ok, path}, my code is working fine. I guess at the moment the book was being writed that function was a bit different. The book is still in beta version by the way.

There is hoever a bit of the code I don’t yet understand in ProductLive.FormComponent.

def update(%{product: product} = assigns, socket) do

    changeset = Catalog.change_product(product)

    Process.sleep(250) # This bit of code

     |> assign(assigns)
     |> assign(:changeset, changeset)
     |> allow_upload(:image,
       accept: ~w(.jpg .jpeg .png),
       max_entries: 1,
       max_file_size: 9_000_000,
       auto_upload: true,
       progress: &handle_progress/3

I suspect that Process.sleep(250) is for security reason but could someone please elaborate more on this for me ?

Thanks. ^^

I think it might just be to simulate the upload progress because working locally the upload is so quick.

I might be wrong though.

1 Like

Thanks for pointing me in that direction. You’re probably right because no matter how much I think about it, I don’t see any other reason. The only concern is that this delay is too short to really notice anything on the scale of human perception.

Also when I played around with increasing the delay to 5 seconds, all it does is delay the first render of the modal form for 5s. It’s a bit normal because the instruction was given in the update/2 function of a live component.

Also later in the book we used “:timer.sleep(1000)” at the top of the handle_progress/3 function to have time to see the progress of the upload.

I think I’ll report this as an error to the book publisher to see if anything ever comes of it.

Anyway thanks again.

1 Like

I don’t know if a moderator would be kind enough to edit the original question of this thread… I’d like to rephrase it as follows:

Is there any reason to use Process.sleep/1 in the update/2 function of a live component when allowing file upload?

Please what do you think? (Maybe in better English?)

Thanks ^^

I was puzzled by the same thing and that was the first assumption I came to beyond that it’s just an oversight. As you point out it’s still in beta.

Either way, I’m really enjoying it.

1 Like

Another option, and the one I prefer over sleep, is to reduce the :chunk_size of your uploads to something really small, like 128 (bytes). By default we upload something like 8MB chunks so it’s definitely hard to see progress unless your uploads are massive.


This is a really great solution because it fixes another problem I was facing.

To allow the user to cancel an upload in progress, as suggested here (Uploads — Phoenix LiveView v0.17.11), I noticed that when I use the solution of the timer, there are undesirable effects if the file is not very large. For example, I manage to press the cancel button, and the download stops but the page also freezes then I see sometimes an error in the console like:

[error] GenServer #PID<0.648.0> terminating
** (stop) exited in: GenServer.call(#PID<0.654.0>, :consume_start, :infinity)
** (EXIT) no process: the process is not alive or there’s no process currently associated with the given name, possibly because its application isn’t started
(elixir 1.13.4) lib/gen_server.ex:1030: GenServer.call/3
(phoenix_live_view 0.17.11) lib/phoenix_live_view/upload_channel.ex:15: Phoenix.LiveView.UploadChannel.consume/3

It’s as if the file has already finished downloading before the arrival of the instruction to stop, which happens anyway precisely because of the timer.

With your new suggestion that I just tested, everything is working well as expected. Thank you so much! ^^

1 Like