asset_delivery

package module
v0.0.0-...-be9f7af Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 23, 2026 License: MIT Imports: 25 Imported by: 0

README

Asset Delivery

Delivers resized assets (images) in response to HTTP requests. It contains two parts:

  • Delivery server (asset-delivery Cloud Run service)
  • Resize worker (asset-resize Cloud Run service)

Both binaries are built from a single image (cloud/build.Dockerfile) and copied into per-service runtime images. The pipeline is wired in cloudbuild.yaml.

Delivery Server

The delivery server attempts to find an existing resized file from a storage location. If the resized file is found it returns the resized file. Otherwise, it delivers the original file and publishes a resize request to the asset-delivery-resize Pub/Sub topic.

HTTP Request

Each request needs the following URL parameters:

  • width
  • url
  • encoding (e.g., webp, jpeg, png)

For example, to request a version of https://host/path with width=100 and encoding=webp:

https://[host]?width=100&url=https://host/path&encoding=webp
Environment Variables
  • BUCKET: GCP Storage bucket name
  • HOST: GCP Storage host (optional). Used by emulators.
Command-Line Arguments
  • address: Bind address. Defaults to 0.0.0.0:80.
  • credentials: Path to a Google JWT file.
  • allow: Comma-separated allowed hosts for the url query param. Empty allows any.
  • project-id: Google Project ID (for logging & pubsub).

Resize Worker

The resize worker consumes messages from the asset-delivery-resize Pub/Sub topic via a push subscription. Each push delivery is an HTTP POST with the Pub/Sub envelope as the body (see Pub/Sub push docs). The worker unmarshals the embedded ResizeOptions, resizes the source image, and writes the result to the configured GCS bucket.

HTTP status drives Pub/Sub redelivery:

  • 2xx — message acked
  • 4xx — permanent failure (e.g., malformed payload); routed to dead letter after maxDeliveryAttempts
  • 5xx — transient failure; Pub/Sub retries with backoff
Environment Variables
  • PROJECTID: Google Project ID (used for Cloud Logging)
  • BUCKET: GCP Storage bucket name
  • HOST: GCP Storage host (optional)
  • DEFAULT_CACHE_CONTROL: Fallback Cache-Control value when the upstream response carries none
  • PORT: Bind port (Cloud Run sets this; defaults to 8080)
Pub/Sub Push Subscription

The push subscription on projects/connect-1321/topics/asset-delivery-resize should be configured to POST to the asset-resize Cloud Run service URL. For authenticated push, set the subscription's push auth service account and grant it roles/run.invoker on asset-resize. Configure a dead-letter topic + maxDeliveryAttempts to avoid hot-looping on poison messages.

Documentation

Index

Constants

View Source
const MaxImageDimension = 4096
View Source
const ResizeTopic = "asset-delivery-resize"

PubSub topic for sending and receiving resize request

Variables

View Source
var (
	ErrFileNotHandled = errors.New("file type not handled")
	ErrInvalidBounds  = errors.New("invalid image bounds")
)
View Source
var ErrNoFile = errors.New("no file")

Functions

func DefaultImageDecode

func DefaultImageDecode(r io.Reader) (image.Image, error)

func GetImage

func GetImage(url string) ([]byte, string, error)

func ImageToBytes

func ImageToBytes(i image.Image, hint string, quality int) (*bytes.Buffer, error)

func NewGCloudLogger

func NewGCloudLogger(project, name string, opts ...option.ClientOption) (*logging.Client, *logger.Google, error)

func ReaderToImage

func ReaderToImage(r io.ReadSeeker, hint string) (image.Image, string, error)

ReaderToImage decodes r as an image, using hint's extension to pick the decoder when it names a supported format and falling back to image.Decode otherwise. The returned format is the auto-detected format name ("jpeg", "png", "webp", ...) when the fallback path is taken, or the format implied by the hint when the typed decoder succeeds. Callers can use it to choose an output encoding when the hint URL has no extension.

func Resize

func Resize(fs FileSystem, opts ResizeOptions) error

func ResizeImage

func ResizeImage(img image.Image, target uint) (image.Image, error)

func WriteError

func WriteError(w http.ResponseWriter, err error)

Types

type FileInfo

type FileInfo interface {
	FileInfoWrite
	FileInfoRead
}

type FileInfoRead

type FileInfoRead interface {
	Created() time.Time
}

type FileInfoWrite

type FileInfoWrite interface {
	CacheControl() string
}

type FileSystem

type FileSystem interface {
	FromVolume(string) FileSystem
	ObjectURL(string) string
	Info(string) (FileInfo, error)
	ReadCloser(string) (io.ReadCloser, error)
	Write(string, io.Reader, FileInfoWrite) error
	Delete(string) error
}

type GCloudFileInfo

type GCloudFileInfo struct {
	// contains filtered or unexported fields
}

func (*GCloudFileInfo) CacheControl

func (i *GCloudFileInfo) CacheControl() string

func (*GCloudFileInfo) Created

func (i *GCloudFileInfo) Created() time.Time

type GCloudFileSystem

type GCloudFileSystem struct {
	Client *storage.Client
	Host   string
	Bucket string
	// contains filtered or unexported fields
}

func NewGCloudFileSystem

func NewGCloudFileSystem(opts ...option.ClientOption) (*GCloudFileSystem, error)

func (*GCloudFileSystem) Delete

func (fs *GCloudFileSystem) Delete(filename string) error

func (*GCloudFileSystem) FromVolume

func (fs *GCloudFileSystem) FromVolume(name string) FileSystem

func (*GCloudFileSystem) GetBucket

func (fs *GCloudFileSystem) GetBucket(bucket string) *storage.BucketHandle

func (*GCloudFileSystem) Info

func (fs *GCloudFileSystem) Info(filename string) (FileInfo, error)

func (*GCloudFileSystem) ObjectURL

func (fs *GCloudFileSystem) ObjectURL(filename string) string

func (*GCloudFileSystem) ReadCloser

func (fs *GCloudFileSystem) ReadCloser(filename string) (io.ReadCloser, error)

func (*GCloudFileSystem) Write

func (fs *GCloudFileSystem) Write(filename string, r io.Reader, info FileInfoWrite) error

type GCloudPubSub

type GCloudPubSub struct {
	logger.Logger
	*pubsub.Client
}

func NewGCloudPubSub

func NewGCloudPubSub(projectId string, opts ...option.ClientOption) (*GCloudPubSub, error)

func (*GCloudPubSub) Publish

func (p *GCloudPubSub) Publish(subj string, data []byte) error

type HTTPError

type HTTPError interface {
	Status() int
	Error() string
}

type Messager

type Messager interface {
	Publisher
	Subscriber
	Close()
}

type ParamError

type ParamError struct {
	Param     string
	Detail    string
	RootError error
}

func (*ParamError) Error

func (err *ParamError) Error() string

func (*ParamError) Root

func (err *ParamError) Root() error

func (*ParamError) Status

func (err *ParamError) Status() int

type Publisher

type Publisher interface {
	Publish(subj string, data []byte) error
}

type ResizeOptions

type ResizeOptions struct {
	Width        uint
	Location     string
	HashSum      string
	Encoding     string
	Prefix       string
	CacheControl string
}

func (*ResizeOptions) DesiredEncoding

func (opts *ResizeOptions) DesiredEncoding() string

func (*ResizeOptions) ObjectKey

func (opts *ResizeOptions) ObjectKey() string

func (*ResizeOptions) PopulateHash

func (opts *ResizeOptions) PopulateHash()

type ResizeOptionsProcessed

type ResizeOptionsProcessed struct {
	ResizeOptions
	URL   *url.URL
	Force bool
}

func NewResizeOptionsFromQuery

func NewResizeOptionsFromQuery(m map[string][]string) (ResizeOptionsProcessed, error)

type RootError

type RootError interface {
	Root() error
}

type Subscriber

type Subscriber interface {
	Subscribe(subj string, h func([]byte)) (Subscription, error)
}

type Subscription

type Subscription interface {
	Unsubscribe()
}

type SystemError

type SystemError struct {
	RootError error
	Detail    string
}

func (*SystemError) Error

func (err *SystemError) Error() string

func (*SystemError) Root

func (err *SystemError) Root() error

func (*SystemError) Status

func (err *SystemError) Status() int

type WriteInfo

type WriteInfo struct {
	// contains filtered or unexported fields
}

func (*WriteInfo) CacheControl

func (i *WriteInfo) CacheControl() string

Directories

Path Synopsis
cmd
delivery command
resize command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL