tovarchristian21

tovarchristian21

Image Processing API Architecture

Hello everyone, I will start an image processing API in elixir that will have 2 main functionalities. The 1st functionality is to simply upload images to an S3 bucket. The 2nd functionality is the critical one, since this api will be consumed by a Ruby app for exhibiting several of these digital assets in different sizes and applying different transformations. My main concern is not the dependency that will process the images in Elixir, but instead is the architecture behind the api. The ruby app will be constantly fetching the images from S3 via the elixir app, I’ve been researching several technologies, and one that caught my attention was Broadway. I’ve used gen stage before, however I’m not sure if Broadway is exactly what I’ll need, how can I now that my system can handle all of those requests? that is one of my main concerns. If you guys have any suggestions or tips in order to achieve what I’ve mentioned, I appreciate it.

Most Liked Responses

drl123

drl123

There are a few SAS offerings out there that do something similar (https://www.imgix.com/ is another one). The advantage is that they take care of supporting all of the new image types that come out (HEIC/HEIF, etc.) and you can focus on your core business logic. All depends what kind of ‘transformations’ you are doing and if you need the Exif data maintained/updated in the images after modification (I think Imagizer strips the Exif out by default). If you can live with the limitations of these SAS offerings, you may not even need the second app since they’d be doing the hard work…it would essentially just become an asset server.

Another benefit of Cloudfront is that the cache gets copies stored geographically close to the end users, so it improves their page load times, even if your api has only one availability zone.

Without knowing your entire use model, not sure if Broadway, GenStage or even Flow would actually solve your bandwidth problem or not. If the end users expect the image to be served right away, back-pressure on the asset delivery isn’t the greatest solution and you’ll need to build a queuing or retry system in the consuming app to deal with that back-pressure/delay that the Elixir server would be applying. If this is the case, and you actually have a throughput problem, you might look at ways to alleviate the bottleneck before adding a lot of overhead in managing the back-pressure on both sides.

polypush135

polypush135

So I’ve really been kicking this idea around for sometime.

I know this maybe not the ideal solution for you, but I’m activity working to learn rust so I can make a web assembly app that will scale the images client side and then I will have my client side app directly upload them via signed urls to s3. I think cost alone will make this a much more effective solution long term.

Photon: A WebAssembly Image Processing Library looks promising

drl123

drl123

Yes I’ve used this before and it performed quite well. If the files are really large, you may need to scale them down and then apply the transforms to the resized image if it is taking too long. If you find you need more than one instance, you just set up a load-balancer with multiple EC2’s behind it and auto-scale them. There’s an AMI for Imagizer in the AWS marketplace and you spin up an EC2 instance using it, then just pass query string params for the transforms. I believe Imagizer’s documentation explains all of the setup…been a while since I looked at it last (and I wasn’t involved in the initial set up either).

We actually used it without any middle app to do transforms right from the JS front-end of the app. In that case, the main api app only managed the pre-signed URLs for upload and the access keys for reading and Imagizer did the rest of the hard work.

Cloudfronting what is a common request eliminates much of the load from the main app freeing up the resources for the rest of the business logic. This also means you don’t have to store the same image in multiple sizes…the other sizes are just transforms and just pull from the cache, falling back to a new request only if they’ve expired, which just causes them to be re-cached. It’s pretty efficient.

Cloudfront is both super cheap, and super performant for the end user because it keeps copies geographically close to them, so time to glass is kept to a minimum (way faster than trying to do this on the fly, even with parallel transforms going on).

Technically, you could even use infrequent access instead of standard S3 with the CF caching and save on your storage costs too.

Again, it all depends on your application and performance needs. For our use case, it worked extremely well and was nearly maintenance free. The only time we had to touch the mechanism was when a new version of the AMI came out…otherwise, it just worked. Depending upon your request volumes (and keep in mind that CF helps keep that minimal after initial caching) you could also use their SAS offering and not have to deal with setting up the EC2 instances. With our volumes, EC2 was a cheaper solution, but you will need to evaluate that for yourself.

Hope this was helpful.

Where Next?

Popular in Discussions Top

mmmrrr
Just saw that dhh announced https://hotwire.dev/ Is it just me or is this essentially live view? :smiley: Although I like the “iFrame-e...
New
praveenperera
How We Replaced React with Phoenix By: Thought Bot
New
nunobernardes99
Hi there Elixir friends :vulcan_salute: In a recent task I was on, I needed to check in two dates which of them is the maximum and which...
New
nburkley
AWS re:Invent is on at the moment with some interesting announcements. One new feature in particular is the Lambda Runtime API for AWS La...
New
AstonJ
I’ve just started the Phoenix part of the utterly brilliant online course by @pragdave. On generating the Phoenix app he uses the --no-ec...
New
rower687
Hi all, I’ve been reading a lot about the “let it crash” term and how supervising processes and the whole messaging passing make an elixi...
New
eteeselink
Hi all, In the last days, two things happened: A blog post titled “They might never tell you it’s broken” made the rounds. It’s about ...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
AstonJ
Can you believe the first professionally published Elixir book was published just 8 years ago? Since then I think we’ve seen more books f...
New

Other popular topics Top

siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43622 214
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New

We're in Beta

About us Mission Statement