### Install Go (OSX) Source: https://github.com/contribsys/faktory/wiki/Development Use Homebrew to install Go on OSX. ```bash brew install go ``` -------------------------------- ### Install Faktory on macOS using Homebrew Source: https://github.com/contribsys/faktory/wiki/Installation Install Faktory on macOS using the Homebrew package manager. After installation, run the `faktory` command to start the server. ```bash > brew install contribsys/faktory/faktory [2 minutes pass] > faktory ``` -------------------------------- ### Start Redis Replica Instance Source: https://github.com/contribsys/faktory/wiki/Ent-Redis-Gateway Command to start the Redis replica instance using the configured 'replika.conf' file. ```shell /usr/local/bin/redis-server replika.conf ``` -------------------------------- ### Install Faktory with Homebrew Source: https://github.com/contribsys/faktory/wiki/Getting-Started-Ruby Use Homebrew to install Faktory on macOS. Ensure Faktory is running in a terminal before proceeding. ```bash brew tap contribsys/faktory brew install faktory ``` -------------------------------- ### Install Redis (OSX) Source: https://github.com/contribsys/faktory/wiki/Development Use Homebrew to install Redis on OSX. ```bash brew install redis ``` -------------------------------- ### Consumer HELLO for Non-Secured Server Source: https://github.com/contribsys/faktory/blob/main/docs/protocol-specification.md Example of a consumer client sending a HELLO command to a non-secured Faktory server, including required fields. ```text S: +HI {"v":2} C: HELLO {"hostname":"localhost","wid":"4qpc2443vpvai","pid":2676,"labels":["golang"],"v":2} ``` -------------------------------- ### Producer HELLO for Non-Secured Server Source: https://github.com/contribsys/faktory/blob/main/docs/protocol-specification.md Example of a producer client sending a HELLO command to a non-secured Faktory server. ```text S: +HI {"v":2} C: HELLO {"v":2} ``` -------------------------------- ### Producer HELLO for Secured Server Source: https://github.com/contribsys/faktory/blob/main/docs/protocol-specification.md Example of a producer client sending a HELLO command to a secured Faktory server, including password hash. ```text S: +HI {"v":2,"s":"123456789abc","i":1735} C: HELLO {"pwdhash":"1e440e3f3d2db545e9129bb4b63121b6b09d594dae4344d1d2a309af0e2acac1","v":2} ``` -------------------------------- ### Dockerfile for Faktory Enterprise Source: https://github.com/contribsys/faktory/wiki/Ent-Installation This Dockerfile sets up the environment to build and install Faktory Enterprise. It installs dependencies, adds the Faktory repository, and extracts the Faktory binary. ```dockerfile ARG FAKTORY_VERSION RUN echo "debconf debconf/frontend select Noninteractive" | debconf-set-selections \ && apt-get update \ && apt-get -y install \ binutils \ ca-certificates \ gnupg2 \ software-properties-common \ && echo "deb https://dl.contribsys.com/fent/apt stable main" > /etc/apt/sources.list.d/faktory.list \ && echo "machine dl.contribsys.com login ${FAKTORY_USERNAME} password ${FAKTORY_PASSWORD}" > /etc/apt/auth.conf \ && APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn apt-key adv --fetch-keys https://dl.contribsys.com/public.gpg \ && apt-get update \ && apt download faktory-ent \ && ar -x faktory-ent*.deb \ && gunzip data.tar.gz \ && tar xvf data.tar ./usr/bin/faktory ``` ```dockerfile FROM contribsys/faktory:${FAKTORY_VERSION:-latest} AS bundler # required ARG FAKTORY_LICENSE COPY --from=builder /usr/bin/faktory / RUN echo "${FAKTORY_LICENSE}" >> /etc/faktory/license EXPOSE 7419 7420 CMD ["/faktory", "-w", ":7420", "-b", ":7419", "-e", "development"] ``` -------------------------------- ### Client-side I/O Deadlines Example Source: https://github.com/contribsys/faktory/blob/main/Changes.md Demonstrates the format of client-side I/O deadline errors that may occur due to slow or misconfigured networks. ```text read tcp 127.0.0.1:63027->127.0.0.1:7419: i/o timeout ``` -------------------------------- ### Install Faktory on Linux (DEB/RPM) Source: https://github.com/contribsys/faktory/wiki/Installation Use these commands to install Faktory binary packages on Debian/Ubuntu (DEB) or CentOS/RHEL (RPM) based Linux distributions. Ensure you have the correct filename for the package. ```bash # DEB distros like Ubuntu dpkg -i # RPM distros like CentOS yum install ``` -------------------------------- ### Run Faktory Worker in Ruby Source: https://github.com/contribsys/faktory/wiki/Getting-Started-Ruby Install dependencies with Bundler and start the Faktory worker process. The `-r ./app.rb` flag loads your worker definitions. ```bash bundle bundle exec faktory-worker -r ./app.rb ``` -------------------------------- ### Client Connection - HELLO Command Source: https://github.com/contribsys/faktory/blob/main/docs/protocol-specification.md Details the HELLO command used by clients to establish a connection and provide necessary information to the Faktory server. This includes required fields for consumers and examples for both non-secured and protected server connections. ```APIDOC ## Client Connection - HELLO Command ### Description Clients use the `HELLO` command to initiate a connection with the Faktory server, providing version information and, for consumers, specific host and worker details. ### Method C: HELLO ### Parameters #### Request Body - **v** (Integer) - Required - Protocol version. - **hostname** (String) - Optional (Required for Consumers) - Name of the host running the worker. - **wid** (String) - Optional (Required for Consumers) - Globally unique identifier for the worker. - **pid** (Integer) - Optional (Required for Consumers) - Local process identifier for the worker. - **labels** (Array[String]) - Optional (Required for Consumers) - Labels applied to the worker for targeted work. - **pwdhash** (String) - Optional (Required for Protected Servers) - Hash of the password for authentication. ### Request Example (Consumer) ```json { "hostname": "localhost", "wid": "4qpc2443vpvai", "pid": 2676, "labels": ["golang"], "v": 2 } ``` ### Request Example (Producer to non-secured server) ```json { "v": 2 } ``` ### Request Example (Producer to protected server) ```json { "pwdhash": "1e440e3f3d2db545e9129bb4b63121b6b09d594dae4344d1d2a309af0e2acac1", "v": 2 } ``` ### Response #### Success Response (200) - **+OK** (Simple String) - Connection established successfully. #### Error Response - **Error** - Indicates an issue with the HELLO command or authentication. ``` -------------------------------- ### Install Faktory Enterprise on OSX Source: https://github.com/contribsys/faktory/wiki/Ent-Installation Extract the Faktory Enterprise binary and copy it to your PATH. Ensure you are in development mode as production requires a license. ```shell tar xjf faktory-ent*.osx.tbz cp ./faktory /usr/local/bin /usr/local/bin/faktory --help ``` -------------------------------- ### Configure APT Repository for Faktory Enterprise on Linux Source: https://github.com/contribsys/faktory/wiki/Ent-Installation Add the Faktory Enterprise APT repository and credentials to your system. This allows you to install `faktory-ent` using `apt-get`. ```shell sudo apt-get install -y apt-transport-https deb https://dl.contribsys.com/fent/apt stable main machine dl.contribsys.com login $USERNAME password $PASSWORD curl https://dl.contribsys.com/public.gpg | sudo apt-key add - sudo apt-get update sudo apt-get install -y faktory-ent ``` -------------------------------- ### Configure Faktory with REDIS_URL Source: https://github.com/contribsys/faktory/wiki/Ent-Remote-Redis Set the REDIS_URL environment variable to point to your remote Redis instance when starting Faktory. ```bash REDIS_URL=redis.example.com /usr/bin/faktory ``` -------------------------------- ### Password Hashing Logic for Faktory HELLO Source: https://github.com/contribsys/faktory/blob/main/docs/protocol-specification.md This example demonstrates the required logic for generating a password hash when connecting to a Faktory server that requires authentication. It involves concatenating the password with a salt and repeatedly applying SHA256. ```text hash = password + s for 0..i { hash = sha256(hash) } hex(hash) ``` -------------------------------- ### Start Faktory with Redis Gateway on a Port Source: https://github.com/contribsys/faktory/wiki/Ent-Redis-Gateway Use the FAKTORY_REDIS_PORT environment variable to expose Redis on a specific port. Faktory will bind Redis to localhost. ```shell FAKTORY_REDIS_PORT=16379 /usr/local/bin/faktory -l debug ``` -------------------------------- ### Worker HELLO Message Example Source: https://github.com/contribsys/faktory/wiki/Worker-Lifecycle A sample HELLO message from a worker process to Faktory, including authentication details and worker information. For producers without password requirements, a simpler HELLO is sufficient. ```json HELLO { "hostname":"MikeBookPro.local", "wid":"4qpc2443vpvai", "pid":2676, "labels":["golang"], "pwdhash":"1e440e3f3d2db545e9129bb4b63121b6b09d594dae4344d1d2a309af0e2acac1", "v":2 } ``` ```json HELLO {"v":2} ``` -------------------------------- ### Faktory Worker Output Example Source: https://github.com/contribsys/faktory/wiki/Getting-Started-Ruby Example log output from a Faktory worker processing jobs. This shows successful job completion with timestamps and worker information. ```log 2017-11-10T23:49:31.561Z 49747 TID-oum1sndj0 SomeWorker JID-10560ae319c36e5f INFO: done: 1.002 sec 2017-11-10T23:49:31.562Z 49747 TID-oum1sncuk SomeWorker JID-2a9824174a5f2764 INFO: done: 1.002 sec 2017-11-10T23:49:31.562Z 49747 TID-oum1sndcw SomeWorker JID-afeb409a9904e90e INFO: done: 1.002 sec 2017-11-10T23:49:31.562Z 49747 TID-oum1snd6s SomeWorker JID-036b5b7e1de9321c INFO: done: 1.002 sec 2017-11-10T23:49:31.562Z 49747 TID-oum1nssb8 SomeWorker JID-c233c86097a8e699 INFO: done: 1.002 sec ``` -------------------------------- ### Initial Handshake HI Messages Source: https://github.com/contribsys/faktory/wiki/Worker-Lifecycle Examples of the initial HI message sent by Faktory to a client. The second example shows attributes for password authentication. ```text # no password HI {"v":2} # password required HI {"v":2,"s":"123456789abc","i":1735} ``` -------------------------------- ### Clone Faktory Repository Source: https://github.com/contribsys/faktory/wiki/Development Use this command to get a local copy of the Faktory project repository. ```bash git clone https://github.com/contribsys/faktory ``` -------------------------------- ### Start Faktory with Advanced Redis Gateway Configuration Source: https://github.com/contribsys/faktory/wiki/Ent-Redis-Gateway Configure the Redis gateway using FAKTORY_REDIS_LISTENER with a socat listener string for fine-grained control over the TCP socket. ```shell FAKTORY_REDIS_LISTENER=TCP-LISTEN:16379,fork,bind=someiface,pf=ipv4,reuseaddr /usr/local/bin/faktory -l debug ``` -------------------------------- ### Faktory Job with Options Source: https://github.com/contribsys/faktory/wiki/The-Job-Payload This example demonstrates a Faktory job with additional options like 'reserve_for' to set the reservation timeout and 'retry' to specify the number of retries on failure. ```json { "jid": "123861239abnadsa", "jobtype": "SomeName", "args": [1, 2, "hello"], "reserve_for": 300, "retry": 4 } ``` -------------------------------- ### Run Faktory Docker Container with Persistent Volume Source: https://github.com/contribsys/faktory/wiki/Installation Start a Faktory Docker container with a persistent volume to store job data. This command maps a local `./data` directory to the container's database path and exposes Faktory's web dashboard and client ports. It also sets a password for Faktory. ```bash mkdir data docker run --rm -it \ -v ./data:/var/lib/faktory/db \ -e "FAKTORY_PASSWORD=some_password" \ -p 127.0.0.1:7419:7419 \ -p 127.0.0.1:7420:7420 \ contribsys/faktory:latest \ /faktory -b :7419 -w :7420 -e production ``` -------------------------------- ### Setup Ruby Gemfile for Faktory Source: https://github.com/contribsys/faktory/wiki/Getting-Started-Ruby Add the `faktory_worker_ruby` gem to your Gemfile to use Faktory with your Ruby application. ```ruby source "https://rubygems.org" gem 'faktory_worker_ruby' ``` -------------------------------- ### Run Faktory Docker Container without Persistent Volume Source: https://github.com/contribsys/faktory/wiki/Installation Start a Faktory Docker container without a persistent volume. This is useful for development as the job database will start empty on each restart. It exposes Faktory's web dashboard and client ports. ```bash docker run --rm -it \ -p 127.0.0.1:7419:7419 \ -p 127.0.0.1:7420:7420 \ contribsys/faktory:latest ``` -------------------------------- ### Nginx Reverse Proxy Configuration for Faktory UI Source: https://github.com/contribsys/faktory/wiki/Security Example Nginx configuration for proxying requests to the Faktory Web UI. It sets necessary headers for correct routing and scheme detection. ```nginx location /faktory { proxy_set_header X-Script-Name /faktory; proxy_pass http://127.0.0.1:7420; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Scheme $scheme; proxy_set_header X-Real-IP $remote_addr; } ``` -------------------------------- ### Push Job with Priority in Faktory Source: https://github.com/contribsys/faktory/blob/main/Changes.md Example of pushing a job with a specified priority. Higher numbers indicate higher priority. If not specified, the default priority is 5. ```json {"jid":"12o31i2u3o1","jobtype":"FooJob","args":[1,2,3],"priority":8} ``` -------------------------------- ### Docker Service Creation with Faktory Password Secret Source: https://github.com/contribsys/faktory/wiki/Security Mount the Faktory password secret into the Faktory container. If FAKTORY_PASSWORD starts with '/', it's treated as a file path. ```bash $ docker service create --name faktory --secret faktory_password --env FAKTORY_PASSWORD=/run/secrets/faktory_password contribsys/faktory:latest ``` -------------------------------- ### Configure Cron Job with Expiry Source: https://github.com/contribsys/faktory/blob/main/Ent-Changes.md Example TOML configuration for a cron job that runs every 5 minutes and has an expiry of 60 seconds. Supports custom job arguments. ```toml [[cron]] schedule = "*/5 * * * *" [cron.job] type = "FiveJob" args = [] [cron.job.custom] expires_in = 60 ``` -------------------------------- ### Set Job Reserve Timeout Source: https://github.com/contribsys/faktory/wiki/Worker-Lifecycle Examples of how to set the 'reserve_for' timeout for a job, which determines how long a worker has to ACK or FAIL a job before it's released. ```ruby # ruby faktory_options reserve_for: 1.hour ``` ```json # raw JSON "reserve_for": 3600, ``` -------------------------------- ### Prepare Faktory Dependencies (Linux) Source: https://github.com/contribsys/faktory/wiki/Development Run this command after cloning to download Go dependencies for the Faktory project on Linux. ```bash make prepare ``` -------------------------------- ### Setting Unique Job with Unlock Policy in Go Source: https://github.com/contribsys/faktory/wiki/Ent-Unique-Jobs To control when a unique job's lock is removed, use `job.SetCustom("unique_until", "start")`. This policy unlocks the job just before it starts executing, which can help mitigate race conditions but may lead to duplicate enqueuing if the job fails. ```go job := faktory.NewJob("sometype", 1, 2) job.SetCustom("unique_for", 600) # seconds job.SetCustom("unique_until", "start") jid, err := faktory.Push(job) ``` -------------------------------- ### Build Homebrew Package Source: https://github.com/contribsys/faktory/wiki/Development Build a Homebrew package for Faktory, specifying the version. ```bash make VER=$VERSION ``` -------------------------------- ### Prepare for Release (Ent) Source: https://github.com/contribsys/faktory/wiki/Development Run this command within the 'ent' directory to prepare for a new release. ```bash make prerel ``` -------------------------------- ### Redis Configuration for a Faktory Replica Source: https://github.com/contribsys/faktory/wiki/Ent-Redis-Gateway Sample redis.conf file for setting up a replica instance. Key settings include 'slaveof' to point to the primary Faktory Redis instance. ```redis bind 127.0.0.1 ::1 port 26379 tcp-backlog 128 tcp-keepalive 30 timeout 120 daemonize no maxmemory-policy noeviction # Specify the server verbosity level. # This can be one of: # debug (a lot of information, useful for development/testing) # verbose (many rarely useful info, but not a mess like the debug level) # notice (moderately verbose, what you want in production probably) # warning (only very important / critical messages are logged) loglevel notice logfile "" # write every 10 seconds if any keys have changed save 10 1 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename /var/lib/faktory-replika.rdb slaveof 127.0.0.1 16379 ``` -------------------------------- ### Build Faktory Binary (Linux) Source: https://github.com/contribsys/faktory/wiki/Development Compile a binary for your current platform using this command on Linux. ```bash make build ``` -------------------------------- ### Create Faktory ECS Cluster with CDK Source: https://github.com/contribsys/faktory/wiki/AWS-ECS Initializes an ECS cluster for Faktory, enabling container insights. Requires VPC and stack context. ```go faktoryCluster := ecs.NewCluster(as.Stack, jsii.String("FaktoryCluster"), &ecs.ClusterProps{ Vpc: as.vpc, ContainerInsights: jsii.Bool(true), }) ``` -------------------------------- ### Configure Faktory Worker Retries Source: https://github.com/contribsys/faktory/wiki/Getting-Started-Ruby Configure job retry settings for a Faktory worker using `faktory_options`. This example sets the retry count to 5. ```ruby class SomeWorker include Faktory::Job faktory_options retry: 5 def perform(*args) puts "Hello, I am #{jid} with args #{args}" sleep 1 end end SomeWorker.perform_async(1, 2, 3) ``` -------------------------------- ### Dockerfile for Faktory Enterprise Source: https://github.com/contribsys/faktory/wiki/Ent-Installation A sample Dockerfile to build a Faktory Enterprise image. It copies the extracted binary and a license file into a base image. ```Dockerfile # Dockerfile FROM contribsys/faktory:latest COPY ./usr/bin/faktory / COPY ./license /etc/faktory/license EXPOSE 7419 7420 CMD ["/faktory", "-w", ":7420", "-b", ":7419", "-e", "development"] ``` -------------------------------- ### Configure Faktory EFS Access Point Source: https://github.com/contribsys/faktory/wiki/AWS-ECS Sets up an EFS access point for Faktory, defining the mount path, POSIX user, and ACL. Ensure UID/GID match container requirements. ```go faktoryFSAP := faktoryFS.AddAccessPoint(jsii.String("FaktoryFSAccessPoint"), &efs.AccessPointOptions{ Path: jsii.String("/var/lib/faktory"), CreateAcl: &efs.Acl{ OwnerGid: jsii.String("1000"), OwnerUid: jsii.String("1000"), Permissions: jsii.String("755"), }, PosixUser: &efs.PosixUser{ Gid: jsii.String("1000"), Uid: jsii.String("1000"), }, }) ``` -------------------------------- ### Place Faktory Enterprise License on Linux Source: https://github.com/contribsys/faktory/wiki/Ent-Installation Create a license file for Faktory Enterprise. This is a required step for production environments. ```shell echo "[your license data]" > /etc/faktory/license ``` -------------------------------- ### Create Nested Batches in Ruby Source: https://github.com/contribsys/faktory/wiki/Ent-Batches Demonstrates creating parent and child batches using the Faktory Ruby client. The parent's success callback waits for the child's success callback, ensuring ordered execution. ```ruby b = Faktory::Batch.new b.success = FooJob.to_s b.jobs do |parent| BatchJob.perform_async child = Faktory::Batch.new child.parent_bid = parent.bid child.success = BarJob.to_s child.jobs do BatchJob.perform_async end end ``` -------------------------------- ### HELLO Command Source: https://github.com/contribsys/faktory/blob/main/docs/protocol-specification.md The initial command issued by a client to authenticate and identify itself to the Faktory server. ```APIDOC ## HELLO Command ### Description The `HELLO` command is mandatory as the first command after receiving the server's `HI` message. It provides client identification and authentication details. ### Method Not applicable (command-based protocol) ### Endpoint Not applicable (command-based protocol) ### Parameters #### Request Body - **v** (Integer) - Required - Protocol version number (must be 2). - **pwdhash** (String) - Optional - Required when server `HI` includes `i` and `s`. Hexadecimal representation of the password hash. ### Request Example ```json { "v": 2, "pwdhash": "abcdef123456..." } ``` ### Response #### Success Response - Simple String "OK" - Client connection accepted, client enters Identified State. #### Error Response - Error - Client connection declined. ### Password Hashing (for Protected Servers) When the server `HI` includes iteration count `i` and salt `s`: 1. Concatenate password with salt: `hash = password + s` 2. Hash `i` times using SHA256: `for 0..i { hash = sha256(hash) }` 3. Convert the final hash to hexadecimal representation for the `pwdhash` field. ``` -------------------------------- ### Retrieve Job Tracking Information Source: https://github.com/contribsys/faktory/wiki/Ent-Tracking Use the `TRACK GET` command with a Job ID (JID) to retrieve its current tracking attributes, including state and update timestamps. This command can be used to follow a job's progress. ```shell > TRACK GET 1234567abcdef { "jid": "1234567abcdef", "state": "enqueued", "updated_at": "2020-01-27T21:10:45Z", } ``` ```shell > TRACK GET 1234567abcdef { "jid": "1234567abcdef", "percent": 12, "desc": "Calculating...", "state": "working", "updated_at": "2020-01-27T21:10:45Z", } ``` ```shell > TRACK GET 1234567abcdef { "jid": "1234567abcdef", "percent": 98, "desc": "Clearing caches...", "state": "success", "updated_at": "2020-01-27T21:10:45Z", } ``` -------------------------------- ### Package Faktory (Linux) Source: https://github.com/contribsys/faktory/wiki/Development Build RPM/DEB package files for Faktory on Linux. ```bash make package ``` -------------------------------- ### Build Faktory Enterprise Docker Image with Arguments Source: https://github.com/contribsys/faktory/wiki/Ent-Installation This Dockerfile uses build arguments for Debian version and Faktory version, and requires username and password for authentication. ```Dockerfile # Dockerfile # Builds a Faktory Enterprise Docker image # Provide your Faktory Enterprise username, password, and license # defaults to sid-slim ARG DEBIAN_VERSION # defaults to latest ARG FAKTORY_VERSION ######################## ### STAGE 1: Builder ### ######################## FROM debian:${DEBIAN_VERSION:-sid-slim} AS builder # required ARG FAKTORY_USERNAME # required ARG FAKTORY_PASSWORD # For a list of versions, login to the following using your credentials # https://dl.contribsys.com/fent/apt/dists/stable/main/binary-amd64/Packages ``` -------------------------------- ### Get Batch Status Source: https://github.com/contribsys/faktory/wiki/Ent-Batches Use the BATCH STATUS command followed by a Batch ID (bid) to retrieve a JSON object containing details about the batch's current state, including total jobs, pending jobs, and failures. ```faktory BATCH STATUS bid ``` ```json {"bid":,"total":17,"pending":14,"failed":3","created_at":"2019-11-18T13:48:25Z","description":"..."} ``` -------------------------------- ### Create Faktory EFS File System Source: https://github.com/contribsys/faktory/wiki/AWS-ECS Initializes an encrypted EFS file system with lifecycle policies and throughput mode for Faktory's persistent storage. Ensure KMS key is configured correctly. ```go faktoryFSEncKey := kms.NewKey(as.Stack, jsii.String("FaktoryFSEncryptionKey"), &kms.KeyProps{ Alias: jsii.String(fmt.Sprintf("efs-%s-faktory-fs", *stackName)), EnableKeyRotation: jsii.Bool(false), // NOTE: key rotation can lead to expoenetial kms cost increases }) faktoryFS := efs.NewFileSystem(as.Stack, jsii.String("FaktoryFS"), &efs.FileSystemProps{ Vpc: as.vpc, EnableAutomaticBackups: jsii.Bool(false), Encrypted: jsii.Bool(true), KmsKey: faktoryFSEncKey, LifecyclePolicy: efs.LifecyclePolicy_AFTER_90_DAYS, OutOfInfrequentAccessPolicy: efs.OutOfInfrequentAccessPolicy_AFTER_1_ACCESS, PerformanceMode: efs.PerformanceMode_GENERAL_PURPOSE, SecurityGroup: faktorySG, ThroughputMode: efs.ThroughputMode_ELASTIC, VpcSubnets: &ec2.SubnetSelection{Subnets: as.vpc.PrivateSubnets()}, RemovalPolicy: cdk.RemovalPolicy_DESTROY, }) ``` -------------------------------- ### Create a New Batch with Callbacks Source: https://github.com/contribsys/faktory/wiki/Ent-Batches Use BATCH NEW to create a batch and define success or complete callback jobs. The command returns the Batch ID (BID). Jobs pushed into this batch must include the BID in their custom data. ```faktory bid = BATCH NEW {"description":"An optional description for the Web UI", "success":{"jobtype":"MySuccessCallback","args":[user_id],"queue":"critical"}, "complete":...} jid = PUSH {...,"custom":{"bid":"b-xxxxxxxxx"}} jid = PUSH {...,"custom":{"bid":"b-xxxxxxxxx"}} BATCH COMMIT ``` -------------------------------- ### Fetching Jobs Source: https://github.com/contribsys/faktory/wiki/Worker-Lifecycle Explains how workers request jobs from Faktory using the FETCH command, including queue prioritization and blocking behavior. ```APIDOC ## Fetching Jobs A worker can request a job from a list of queues with the `fetch` command. ### FETCH Command ``` FETCH critical default low ``` ### Return Value The return value will be nil or the JSON for the job payload. ### Notes * Queues are checked in the order provided. * If all queues are empty, `fetch` will block for 2 seconds, waiting for a job from the first queue. * This short blocking period prevents excessive polling and allows for near-instantaneous job dispatch. * Workers can randomize queue ordering on each FETCH to counteract queue starvation. ``` -------------------------------- ### Client Lifecycle and Commands Source: https://github.com/contribsys/faktory/blob/main/docs/protocol-specification.md Details on client connection states and the recommended usage of BEAT commands for consumers. ```APIDOC ## Client Lifecycle ### Description This section describes the states a client connection can be in and the requirements for clients acting as consumers, particularly regarding the `BEAT` command. ### Connection States: - **Not identified**: The initial state upon connection. - **Identified**: Most commands are valid only in this state. ### Consumer Requirements: - Clients acting as consumers MUST regularly issue `BEAT` commands to the server. - `BEAT` commands are used to recognize state changes initiated by the server. - `BEAT` commands should not be sent more frequently than every 5 seconds. - `BEAT` commands MUST be sent at least every 60 seconds. - A `BEAT` interval of 15 seconds is recommended. - Clients that are not consumers MUST NOT send `BEAT` commands and MUST NOT enter the Quiet or Terminating stages. ``` -------------------------------- ### Server Management Commands Source: https://github.com/contribsys/faktory/blob/main/docs/protocol-specification.md Documentation for server management commands including FLUSH, INFO, and END. ```APIDOC ## Server Management Commands ### `FLUSH` Command #### Description Clears all data from Faktory's internal database, analogous to Redis's `FLUSHDB` command. #### Method `FLUSH` #### Arguments *none* #### Responses - Simple String "OK" - database was cleared - Error - database was not cleared ### `INFO` Command #### Description Retrieves various information about the Faktory server. #### Method `INFO` #### Arguments *none* #### Responses - Bulk String containing various information about the server - Error ### `END` Command #### Description Signals the client's intent to terminate the connection. Clients must not send further commands after sending `END` and receiving an `OK` response. Consumers should ideally complete or fail outstanding jobs before sending `END`. #### Method `END` #### Arguments *none* #### Responses - Simple String "OK" - client connection will be terminated ``` -------------------------------- ### Lint and Test Faktory Code (Linux) Source: https://github.com/contribsys/faktory/wiki/Development Execute this command to verify the code quality and run the test suite for Faktory on Linux. ```bash make lint test ``` -------------------------------- ### Build Faktory Enterprise Docker Image Source: https://github.com/contribsys/faktory/wiki/Ent-Installation Command to build the Faktory Enterprise Docker image. Ensure you replace placeholders with your provided credentials and desired versions. ```shell docker build \ -t faktory-ent \ --build-arg=FAKTORY_USERNAME=username_provided_by_contribsys \ --build-arg=FAKTORY_PASSWORD=password_provided_by_contribsys \ --build-arg=FAKTORY_LICENSE=license_provided_by_contribsys \ --build-arg=FAKTORY_VERSION=1.2.0 \ --build-arg=DEBIAN_VERSION=sid-20191014-slim \ . ``` -------------------------------- ### Create Faktory Service with Network Load Balancer Source: https://github.com/contribsys/faktory/wiki/AWS-ECS Provisions a Fargate service using ecspatterns, configuring a network load balancer with listeners for both Faktory jobs and the web interface. ```go faktorySvc := ecspatterns.NewNetworkMultipleTargetGroupsFargateService(as.Stack, jsii.String("Faktory"), &ecspatterns.NetworkMultipleTargetGroupsFargateServiceProps{ Cluster: faktoryCluster, TaskDefinition: faktoryTaskDef, EnableExecuteCommand: jsii.Bool(true), PropagateTags: ecs.PropagatedTagSource_SERVICE, LoadBalancers: &[]*ecspatterns.NetworkLoadBalancerProps{ { Name: jsii.String("FaktoryNLB"), Listeners: &[]*ecspatterns.NetworkListenerProps{ { Name: jsii.String("FaktoryJobsListener"), Port: jsii.Number(faktoryJobsPort), }, { Name: jsii.String("FaktoryWebListener"), Port: jsii.Number(faktoryWebPort), }, }, PublicLoadBalancer: jsii.Bool(false), }, }, TargetGroups: &[]*ecspatterns.NetworkTargetProps{ { ContainerPort: jsii.Number(faktoryJobsPort), Listener: jsii.String("FaktoryJobsListener"), }, { ``` -------------------------------- ### Enable Statsd Metrics in Faktory Source: https://github.com/contribsys/faktory/wiki/Ent-Metrics Add this TOML section to `/etc/faktory/conf.d/statsd.toml` to enable Statsd metric emission. Configure the `location` of your Statsd server and optionally set a `namespace` and `tags`. ```toml [statsd] # required, location of the statsd server location = "hostname:port" # Prepend all metric names with this value, defaults to 'faktory.' # If you have multiple Faktory servers for multiple apps reporting to # the same statsd server you can use a multi-level namespace, # e.g. "app1.faktory.", "app2.faktory." or use a tag below. #namespace = "faktory." # optional, DataDog-style tags to send with each metric. # keep in mind that every tag is sent with every metric so keep tags short. #tags = ["env:production", "region:us-east-1a"] # Statsd client will buffer metrics for 100ms or until this size is reached. # The default value of 15 tries to avoid UDP packet sizes larger than 1500 bytes. # If your network supports jumbo UDP packets, you can increase this to ~50. #bufferSize = 15 # Calculate the queue latency for this set of queues also queueLatency = ["critical", "default"] ``` -------------------------------- ### Test Faktory Code (OSX) Source: https://github.com/contribsys/faktory/wiki/Development Execute this command to verify the test suite for Faktory on OSX. ```bash make test ``` -------------------------------- ### Consumer Commands - FETCH, ACK, FAIL Source: https://github.com/contribsys/faktory/blob/main/docs/protocol-specification.md Documentation for consumer commands used to fetch jobs, acknowledge completion, and report failures. ```APIDOC ## Consumer Commands ### `FETCH` Command #### Description Requests a job from the Faktory server. Consumers can specify queues to fetch from. If no job is available, it may block for a short period. #### Method `FETCH` #### Arguments - **queue...** (String) - Optional. A list of queues to fetch from, in order of preference. #### Responses - Bulk String containing work unit - A job is available for execution. - Null Bulk String - No work unit is available for execution. - Error ### `ACK` Command #### Description Acknowledges successful completion of a job fetched via `FETCH`. This informs the server that the job is done and can be removed. #### Method `ACK` #### Arguments - **jid** (String) - Required - The unique identifier of the job to acknowledge. #### Responses - Simple String "OK" - ACK was received and accepted - Error - ACK was malformed or rejected ### `FAIL` Command #### Description Reports that a job fetched via `FETCH` resulted in an error. This allows Faktory to handle retries or other error management. #### Method `FAIL` #### Arguments - **jid** (String) - Required - The unique identifier of the job that failed. - **errtype** (String) - Required - The class or type of error that occurred. - **message** (String) - Required - A short description of the error. - **backtrace** (Array[String]) - Optional - A multi-line backtrace of the error. #### Responses - Simple String "OK" - FAIL was received and accepted - Error - FAIL was malformed or rejected ``` -------------------------------- ### Fetch Faktory Stats with INFO Command Source: https://github.com/contribsys/faktory/wiki/Worker-Lifecycle Use the INFO command to retrieve a blob of statistics about the Faktory server. This includes task queue sizes, server details, and uptime. ```shell INFO ``` -------------------------------- ### Configure Faktory Server URL via Environment Variable Source: https://github.com/contribsys/faktory/wiki/Worker-Lifecycle Configure the Faktory server URL using environment variables, following the pattern of other managed services. Set a PROVIDER variable to specify which URL variable to use. ```shell REDISTOGO_URL=redis://... ``` ```shell REDIS_PROVIDER=REDISTOGO_URL ``` ```shell FAKTORYTOGO_URL=tcp://:password@hostname:7419 ``` ```shell FAKTORY_PROVIDER=FAKTORYTOGO_URL ``` -------------------------------- ### Faktory BEAT Command Interaction Source: https://github.com/contribsys/faktory/blob/main/docs/protocol-specification.md Demonstrates the client-server interaction using the BEAT command. Consumers should regularly issue BEAT to maintain liveness and receive state change notifications like 'quiet' or 'terminate'. ```text C: BEAT {"wid": "4qpc2443vpvai","rss_kb":54176} S: +OK C: BEAT {"wid": "4qpc2443vpvai","rss_kb":55272} S: +{"state": "quiet"} C: BEAT {"wid": "4qpc2443vpvai","current_state": "quiet"} S: +{"state": "terminate"} C: END S: +OK ``` -------------------------------- ### Accessing Faktory Redis CLI Source: https://github.com/contribsys/faktory/wiki/Administration Connect to Faktory's private Redis instance using redis-cli via its Unix socket. Use with caution as direct manipulation can crash Faktory. ```bash $ redis-cli -s /var/lib/faktory/db/redis.sock > info ``` -------------------------------- ### Define Faktory Fargate Task Definition Source: https://github.com/contribsys/faktory/wiki/AWS-ECS Sets up a Fargate task definition for Faktory, specifying CPU, memory, and essential container configurations. Includes environment variables, secrets, and port mappings. ```go faktoryTaskDef := ecs.NewFargateTaskDefinition(as.Stack, jsii.String("FaktoryTaskDef"), &ecs.FargateTaskDefinitionProps{ Cpu: jsii.Number(props.faktoryCPU), MemoryLimitMiB: jsii.Number(props.faktoryMemoryLimitMiB), }) ``` ```go faktoryLicense := secretsmanager.Secret_FromSecretCompleteArn( as.Stack, jsii.String("permanent/sandbox/FaktoryLicense"), jsii.String(""), ) ``` ```go faktoryImageAsset := ecs.ContainerImage_FromAsset( jsii.String("../cmd/worker"), &ecs.AssetImageProps{File: jsii.String("Dockerfile.faktory")}, ) ``` ```go faktoryContainer := faktoryTaskDef.AddContainer(jsii.String("FaktoryContainer"), &ecs.ContainerDefinitionOptions{ Image: faktoryImageAsset, Essential: jsii.Bool(true), Environment: &map[string]*string{ "FAKTORY_ENV": jsii.String(props.env), "FAKTORY_PASSWORD": jsii.String(faktoryPassword), }, LinuxParameters: ecs.NewLinuxParameters(as.Stack, jsii.String("FaktoryContainerLinuxParams"), &ecs.LinuxParametersProps{ InitProcessEnabled: jsii.Bool(true), // https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html#ecs-exec-considerations }), Logging: ecs.LogDriver_AwsLogs(&ecs.AwsLogDriverProps{ StreamPrefix: stackName, LogRetention: logs.RetentionDays_THREE_MONTHS, // TODO: determine optimal value }), Secrets: &map[string]ecs.Secret{ "FAKTORY_LICENSE": ecs.Secret_FromSecretsManager(faktoryLicense, nil), }, StartTimeout: cdk.Duration_Seconds(jsii.Number(60)), // Recommended values from the Faktory wiki StopTimeout: cdk.Duration_Seconds(jsii.Number(60)), // Recommended values from the Faktory wiki PortMappings: &[]*ecs.PortMapping{ { ContainerPort: jsii.Number(faktoryJobsPort), HostPort: jsii.Number(faktoryJobsPort), }, { ContainerPort: jsii.Number(faktoryWebPort), HostPort: jsii.Number(faktoryWebPort), }, }, }) ``` -------------------------------- ### Client TLS Configuration URL Source: https://github.com/contribsys/faktory/wiki/Security Configure Go and Ruby clients to use TLS by prefixing the URL scheme with 'tcp+tls://'. This ensures encrypted communication with Faktory. ```url FAKTORY_URL=tcp+tls://myhost.example.com:7419 ``` -------------------------------- ### Configure Queue Latency Metrics Source: https://github.com/contribsys/faktory/wiki/Ent-Metrics To enable queue latency metrics, which are more expensive to compute, specify the queues for which latency should be calculated in the `statsd.toml` configuration. ```toml # statsd.toml [statsd] queueLatency = ["default", "bulk"] ``` -------------------------------- ### Configure Faktory with REDIS_PROVIDER Source: https://github.com/contribsys/faktory/wiki/Ent-Remote-Redis Use REDIS_PROVIDER to specify an environment variable that holds your Redis connection URL, useful for SaaS Redis providers. ```bash REDIS_PROVIDER=FOO_REDIS_URL /usr/bin/faktory ``` -------------------------------- ### Release OSS Version (Ent) Source: https://github.com/contribsys/faktory/wiki/Development Run this command within the 'ent' directory to release the open-source version. ```bash make ossrel ``` -------------------------------- ### Initial Handshake and Authentication Source: https://github.com/contribsys/faktory/wiki/Worker-Lifecycle Describes the initial connection handshake between a worker and Faktory, including server greetings (HI) and client authentication (HELLO) with password hashing. ```APIDOC ## Initial Handshake On initial connection, Faktory immediately sends a HI message to the client with a JSON hash. The "v" attribute is the version of the protocol the server expects. ### Server Greeting (HI) ``` # no password HI {"v":2} # password required HI {"v":2,"s":"123456789abc","i":1735} ``` If password authentication is required, the hash will include nonce and iterations attributes (the "s" and "i" attributes). ### Client Authentication (HELLO) The client must send a HELLO response. If a password is required, it must include a `pwdhash` parameter calculated using SHA256. ``` HELLO { "hostname":"MikeBookPro.local", "wid":"4qpc2443vpvai", "pid":2676, "labels":["golang"], "pwdhash":"1e440e3f3d2db545e9129bb4b63121b6b09d594dae4344d1d2a309af0e2acac1", "v":2 } > OK ``` For producer-only processes without a password: ``` HELLO {"v":2} ``` ### Definitions * `wid`: worker id, a unique random string for every worker process. * `hostname`/`pid`: specifics about the machine and process for this worker (informational). * `labels`: application-specific labels, shown in the Web UI. * `pwdhash`: used to authenticate each connection. * `v`: the protocol version the client expects. ``` -------------------------------- ### Backup Faktory Redis Data Source: https://github.com/contribsys/faktory/wiki/Storage To back up your Faktory queue data when using the OSS version with a local Redis instance, simply copy the RDB file. Ensure Faktory is stopped before performing the backup to maintain data integrity. ```bash cp /var/lib/faktory/db/faktory.rdb backup.rdb ``` -------------------------------- ### Pull Faktory Docker Image Source: https://github.com/contribsys/faktory/wiki/Installation Download the latest Faktory Docker image from Docker Hub. This is the first step before running a Faktory container. ```bash docker pull contribsys/faktory ``` -------------------------------- ### Configure Faktory Cron Jobs with TOML Source: https://github.com/contribsys/faktory/wiki/Ent-Cron Define periodic jobs by creating TOML files in the Faktory configuration directory. Each `[[cron]]` section specifies a job's schedule and details, including type, queue, retries, and custom parameters. ```toml [[cron]] schedule = "*/5 * * * *" [cron.job] type = "FiveJob" queue = "critical" [cron.job.custom] foo = "bar" [[cron]] schedule = "12 * * * *" [cron.job] type = "HourlyReport" retry = 3 [[cron]] schedule = "* * * * *" [cron.job] type = "EveryMinute" ``` -------------------------------- ### Fetch Jobs Command Source: https://github.com/contribsys/faktory/wiki/Worker-Lifecycle Command to request a job from Faktory, specifying a list of queues to check in order. Faktory will block for 2 seconds if all queues are empty. ```text FETCH critical default low ```