Skip to content

jscottmiller/job-queue

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

In-memory job queue

A simple REST service exposing an in-memory job queue.

To run the server, execute ./scripts/run.sh. The server binds to all interfaces on port 8080. This cannot be changed.

To run tests, execute ./scripts/test.sh

Implementation notes

The in-memory queue is implemented as a single slice, grown according to the append built-in. The Queue type maintains this slice, appending new job entries on enqueue and dequeuing jobs by manipulating an index into the slice pointing to the head of the queue. The slice is permitted to grow without bound, though the it will be compacted if more than half of the entries in the slice are empty. Compaction should only reduce the length of the slice and not its capacity, so I'd expect the overall memory usage to stabilize after the service has run for a while. In the worst case, enqueue operations may cause a slice allocation until the size stabilizes, and dequeue operations may trigger a compaction, though on average I would expect both of those operations to execute in constant time. Concluding a job currently requires a scan through a slice of all jobs in progress, though this slice is periodically trimmed and compacted.

To help ensure at-least-once processing, a stale job that was dequeued but not concluded after more than 5 minutes will return to the queue (the 5 minute expiration is not a hard limit and will vary depending on an expiration timer). Assuming that the jobs are idempotent, this provides a simple recovery mechanism if a processor crashes during execution.

No authorization is implemented - any client can perform operations on any job they wish. The only authorization that may be worth performing is to ensure that the client that requests to conclude a job is the same client that dequeued it.

Future work

The tests that are implemented are useful but by no means exhaustive. In particular, more testing of the both the queue compaction and processing timeout.

Parameters could be added to adjust when to compact the queue slice, as well as the slice's initial size and growth strategy. Before implementing any of that, I'd like to add a suite of benchmark tests to 1) ensure that the compaction is working as I expect with larger workloads and 2) to get a baseline for performance and see if those parameters are even needed.

Along the same lines, concurrent access of the queue is handled via a single mutex around all operations. Benchmarking would help uncover the performance impact of this, and in particular I'd be curious to see how the more expensive operations (compaction, stale job search) impact concurrent requests.

The documentation is lacking. I'd like to add godoc comments to the Queue implementation to document the behavior and gotchas. Behavior would include the compaction and stale job detection, and gotchas should cover cases where the methods may mutate the state of the Job struct that might be surprising (e.g., enqueue overrides the existing value for the job's ID and state).

Finally, the HTTP harness was written quickly and without a lot of bells and whistles. At minimum, I would want to add better logging and error reporting to a production service, basic authentication and authorization middleware, and add environment variables for specifying the port and interface that the server binds to.

About

A simple golang job queue

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors