ImagePipe.ProcessingPool (image_pipe v0.5.0)

Copy Markdown View Source

Limits how many images are processed at once, with a queue for requests that wait for a turn and a deadline for each image.

An ImagePipe instance starts one, configured with its :pool option, unless its configuration names one in :processing_pool. Start a pool yourself to share it between instances:

children = [
  {ImagePipe.ProcessingPool, name: MyApp.Pool, max_concurrency: 8, max_queue: 16},
  {ImagePipe, name: MyApp.Images, processing_pool: MyApp.Pool, sources: [...]},
  MyAppWeb.Endpoint
]

Every configuration that names the pool with :processing_pool shares its capacity, across mounts and ImagePipe.run/4 calls on the same node. Workers finishing after a timeout or cancellation keep their slots until their operations and cleanup finish. Limiting concurrent processing covers choosing the limits and what counts toward them.

Errors

ImagePipe.run/4 returns these errors, and a request gets a 503 for each:

  • {:processing, :overloaded} - the queue is full.
  • {:processing, :queue_timeout} - the request waited longer than :queue_timeout.
  • {:processing, :timeout} - the image took longer than :processing_timeout.
  • {:processing, :unavailable} - the pool isn't running.

Over HTTP, the 503 for :overloaded or :queue_timeout has a Retry-After header: :queue_timeout in whole seconds, rounded up.

A request with low priority waits for spare capacity. It starts only when no normal request is waiting and fewer than :low_priority_max_concurrency low-priority requests hold slots. A normal request that finds the queue full takes the place of the newest waiting low-priority request, which fails with {:processing, :overloaded}.

Options

  • :name (atom/0) - Name that ImagePipe.config/1's :processing_pool refers to.

  • :max_concurrency (pos_integer/0) - Required. Most images processed at once.

  • :low_priority_max_concurrency (pos_integer/0) - Most low-priority images processed at once. Defaults to half of :max_concurrency, rounded down, and at least 1.

  • :max_queue (non_neg_integer/0) - Most requests waiting for a turn. A request that finds the queue full fails with {:processing, :overloaded}, unless it has normal priority and a low-priority request is waiting. Then the newest waiting low-priority request fails instead. With 0, requests never wait. The encode of an image decoded while its original downloaded is a second turn for its request, and isn't counted or turned away. The default value is 1024.

  • :queue_timeout (pos_integer/0) - Longest wait for a turn, in milliseconds. A request that waits longer fails with {:processing, :queue_timeout}. The default value is 10000.

  • :processing_timeout (pos_integer/0) - Request deadline once processing starts, in milliseconds, from reading the original to encoding the last byte. Without a usable spool directory, it also covers sending all but the last 4 MB to a slow client. A request that takes longer fails with {:processing, :timeout}. Its worker keeps the slot until the current operation and cleanup finish. The default value is 30000.

Summary

Functions

Returns a specification to start this module under a supervisor.

Starts a pool with validated admission and timeout options.

Returns the number of workers holding processing slots and of requests waiting, in total and for low priority, as %{active: 3, queued: 1, low_active: 1, low_queued: 1}.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

start_link(opts)

Starts a pool with validated admission and timeout options.

stats(pool)

Returns the number of workers holding processing slots and of requests waiting, in total and for low priority, as %{active: 3, queued: 1, low_active: 1, low_queued: 1}.

Active workers include those finishing after a timeout or cancellation.