CHANGELOG.md

# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [0.7.3] — 2023-07-18

- Update dependency constraints for `telemetry`, `nimble_parsec`, `redix`, and `gen_stage`

## [0.7.2] — 2021-05-12

- Update and loosen dependency constraints

## [0.7.1] — 2020-05-06

- Update and loosen dependency constraints, particularly for nimble parsec

## [0.7.0] - 2019-05-13

### Added

- [Reporter.Instrumenter] Bump telemetry version.

## [0.6.0] - 2019-03-18

### Added

- [Kiq.Encoder] Wrap `Jason.encode` and attempt to sanitize terms that can't be
  represented as JSON. This is primarily a safeguard against enqueuing jobs with
  structs or tuples as arguments.

### Fixed

- [Kiq.Client.Resurrection] Correct usage of SCAN to ensure all backup queues
  will be found for re-enqueueing.

### Changed

- [Kiq.Job] Keys within job arguments are no longer converted to atoms. This is
  for safe execution and is in line with how Phoenix passes controller
  arguments.
- [Kiq.Client] Enqueue all jobs in a single pipelined command. This moves all of
  the unique, scheduling and enqueueing logic into a lua script. The script
  reduces the number of round trips to redis and enabled pipelining. Overall
  this improved job enqueue/execute performance from 1800 jobs/sec to slightly
  more than 3700 jobs/sec.

## [0.5.0] — 2018-12-14

### Added

- [Kiq.Periodic] Periodic jobs support! Periodic (AKA "Cron") jobs are
  registered with a schedule and enqueued automatically by Kiq accordingly.
  This is a fully fledged alternative to using a separate scheduler such as
  [Quantum][quantum].

[quantum]: https://github.com/quantum-elixir/quantum-core

### Changed

- [Kiq.Reporter.Logger] Job lifecycle logging uses the format `event:
  "job_status"` instead of `status: "status"`. For example, if you were checking
  logs for `"status":"finished"` you would now look for
  `"event":"job_finished"`.

### Fixed

- [Kiq.Client] Eliminate use of `MUTLI/EXEC` for stats and queuing. This caused
  a race condition that could prevent stats being recorded and jobs from being
  enqueued.

## [0.4.0] — 2018-12-03

### Added

- [Reporter.Retryer] Dead jobs support! Jobs with exhausted retries are moved
  into the `dead` set. Workers or jobs may be configured with `dead: false` to
  prevent being moved to the dead set.

- [Kiq] Quiet support! The `configure/1` function can be used to set runtime
  configuration. Calling `MyKiq.configure(quiet: true)` will stop all queues
  from starting new jobs while allowing currently running jobs to finish. This
  can be used for graceful shutdown and smooth blue/green deployment.

- [Reporter.Instrumenter] A new reporter that provides instrumentation data
  through [Telemetry](https://hexdocs.pm/telemetry). Reporting job execution
  metrics only requires attaching to `[:kiq, :job, event]` events.

- [mix kiq.gen.supervisor] A new generator to create an initial Kiq supervisor
  module.

- [mix kiq.gen.reporter] A new generator to create custom reporters with all of
  the callbacks defined.

- [mix kiq.gen.worker] A new generator to create workers with `retries`, `queue`
  and `dead` specified.

### Changed

- [Script] More functionality, including dequeueing and descheduling, has been
  moved into Lua scripts. To reduce bandwidth and io overhead all `EVAL` usage
  has been replaced with `EVALSHA`.

- [Identity] For purely aesthetic reasons the nonce value is now lower case.

- [Logger] Consistently format logs as JSON. Previously some ad-hoc logs were
  unstructured, which made parsing difficult. Additionally, logs now contain
  `"source":"kiq"` for easier identification.

### Fixed

- [Kiq] In progress backup queues, AKA "Private Queues", are now implemented
  with a hash rather than a list. This ensures that a job can _always_ be
  removed from the backup, regardless of how it is encoded. Previously, when a
  job was enqueued by Sidekiq the serialized version wouldn't match the
  version serialized by Kiq. The `LREM` command requires an exact binary match
  or list elements won't be removed, which caused jobs to linger in the backup
  queue.

## [0.3.0] — 2018-10-28

### Added

- [Kiq] Expiring Job support. Expiring jobs won't be ran after a configurable
  amount of time. The expiration period is set with the `expires_in` option,
  which accepts millisecond values identically to the `unique_for` option.

- [Kiq.Pool] Connection pooling. Recently added benchmarks quickly identified a
  bottleneck in the single Client/Redis connection. A simple random-order pool
  was introduced that allowed the client, queues and reporters to rotate through
  a set of connections. This change alone doubled the enqueue/dequeue
  throughput.

- [Kiq.Client] Reliable push support. Enqueued jobs are now buffered in memory
  and periodically flushed to Redis. If there are any connection errors or Redis
  is down the jobs are retained and flushing is retried with backoff.

- [Kiq.Testing] Sandbox test mode. When `test_mode` is set to `:sandbox` jobs
  will never be flushed to Redis. Each locally buffered job is associated with
  the process that enqueued it, enabling concurrent testing with isolation
  between test runs.

- [Kiq] Leadership election. Useful when coordinating work that should only
  happen on a single node. Internally used to prevent duplicate job
  resurrection, and in the future will be used for periodic jobs.

- [Kiq] Private queues. Ensure terminated jobs are resurrected when the
  application starts up. Unlike the previous job backup mechanism this
  guarantees that only jobs from dead processors are resurrected; in-process
  jobs will never be duplicated.

### Changed

- [Redix] Upgrade from Redix 0.7.X to 0.8.X, which introduced the `noreply_` variant of
  commands.

- [Kiq.Config] Renamed `poll_interval` option to `flush_interval`, and the
  default changed from `1000` to `500`.

### Fixed

- [Kiq] Failing unique jobs would never be retried.

## [0.2.0] — 2018-09-17

### Added

- [Kiq] Unique Job support! Workers, and their corresponding jobs, can now be
  made unique within for a period of time. Until the initial job has succeeded
  it is considered "locked" and all subsequent attempts to enqueue a job with
  the same class, queue and args will be ignored. The unique period is specified
  with the `unique_for` option, which accepts millisecond values for easy
  interaction with the `:timer` module's `minutes/1` and `seconds/1` functions.

### Fixed

- [Kiq.Runner] Correctly convert nested modules binaries into the correct
  worker, i.e.  convert `"Kiq.Workers.Business"` into the module
  `Kiq.Workers.Business`.

- [Kiq.Job] Correctly serialize pid and job payloads when recording a worker's
  running jobs for heartbeats. Incorrectly formatted hashes in Redis will cause
  the Sidekiq "busy" dashboard to crash.

- [Kiq.Heartbeat] Retain the original `ran_at` value for reported jobs. Running
  jobs are now encoded when they are started, preventing repeated JSON encodings
  and allowing the initial `ran_at` value to be used when reporting. Prior to
  this change the job was always reported as being started "Just Now".

- [Kiq.Job] Skip serializing `retry_count` when the value is 0. Sidekiq doesn't
  include a `retry_count` when there hasn't been a retry, which prevents the job
  serialized by Kiq from matching up. If the serialized job doesn't match up
  then the job can't be removed from the backup queue, leading to a buildup of
  duplicate jobs.

## [0.1.0] - 2018-07-31

### Added

Initial release, everything was added!

- Job creation
- Worker definition
- Running and configuring queues
- Retries
- Scheduled jobs
- Statistics
- Custom reporters
- Testing support
- Heartbeat reporting

[Unreleased]: https://github.com/sorentwo/kiq/compare/v0.1.0...HEAD
[0.1.0]: https://github.com/sorentwo/kiq/compare/e6106af2506...v0.1.0
[0.2.0]: https://github.com/sorentwo/kiq/compare/v0.1.0...v0.2.0
[0.3.0]: https://github.com/sorentwo/kiq/compare/v0.2.0...v0.3.0
[0.4.0]: https://github.com/sorentwo/kiq/compare/v0.3.0...v0.4.0
[0.5.0]: https://github.com/sorentwo/kiq/compare/v0.4.0...v0.5.0