I have a Phoenix application that downloads (10MB+) files from another server on a specific user action, manipulates them, and then sends them to the user. I want to offload these jobs into a separate Background Job Queue, instead of blocking the current operation and just notify the user when the files are available to download.
defmodule Asset do
# Ecto Model and other stuff...
def download(asset) do
# Long running HTTPoison task that downloads the file,
# manipulates it, and stores to the disk so the user can
# download it later
end
end
Instead of going with an external job processing library or relying on any external programs such as Redis, I want to do this myself while staying in OTP land (mostly as a learning experience). I eventually plan on integrating (A)mnesia to persist job state, but for now I just want to handle them.
I’m hoping these tasks can be offloaded in a simple manner, something like this:
download_job = fn -> Asset.download(some_asset) end
on_complete = fn -> User.notify(user, "SomeAsset is available now") end
# Add a new job to the worker along with an anonymous function
# that gets called when the job is completed
BackgroundWorker.add_job(download_job, on_completed)
I believe GenServer / GenStage is the way to go here, but I don’t have any experience with them to even get started. I would really appreciate some direction (code-wise) on how to implement a very basic Job Worker in Elixir (following proper patterns). I’m also reading up on other GenServer / GenStage examples, but I need some guidance so I can get started.
Would appreciate any pointers I could get. Thanks in advance!