Skip to content

Commit 5499fd0

Browse files
committed
Improve top of README
1 parent d35c328 commit 5499fd0

2 files changed

Lines changed: 100 additions & 26 deletions

File tree

README.md

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,27 @@
1-
# Opsqueue
2-
1+
# Opsqueue: lightweight batch processing queue for heavy loads
32
[![Crates.io Version](https://img.shields.io/crates/v/opsqueue?label=opsqueue%20(binary))](https://crates.io/crates/opsqueue) [![PyPI - Version](https://img.shields.io/pypi/v/opsqueue?label=Python%20client%20library)](https://pypi.org/project/opsqueue/)
43

5-
Making big work horizontally scalable.
6-
7-
Opsqueue does this by being:
8-
9-
* Dead simple
10-
* Super lightweight
11-
* Highly scalable
12-
* Very Flexible
134

145
## Why opsqueue?
156

167
The specific advantages for opsqueue are:
178

18-
* Small codebase that we fully understand
19-
* Full control to do exactly what you want
20-
* One standardized queuing system that can be reused again and again
21-
* A single way to implement monitoring, alerting, and debugging workflows
9+
- Lightweight: small codebase, written in Rust, minimal dependencies
10+
- Optimized for batch processing: we prioritize throughput over latency
11+
- Built to scale to billions of operations
12+
- Built with reliable building blocks: Rust, SQLite, Object Storage (such as S3 or GCS)
13+
- Operationally simple: single binary, embedded database, minimal configuration
14+
- Scales horizontally: you can have many consumers processing work in parallel
15+
- Very flexible: you have full control over how you produce and consume operations. We use a novel prioritization approach where decisions can be made in the middle of ongoing work.
16+
17+
`opsqueue` is a good choice if you have a use case where you first generate a few million operations (an "operation" is any task that can be executed within a few seconds) and then later execute those operations.
2218

2319
## Getting Started:
2420

2521
### 1. Grab the `opsqueue` binary and the Python client library
2622

27-
The binary can be installed from this repo, or build it from source by cloning the repo using `just build` or `cargo build`.
28-
This is a self-contained program, you can run it on a server on its own, include it in a tiny container, etc.
29-
30-
The Python library used by the `Consumer` and `Producer` can be built from source, or (soon) simply be installed from pypi. (`pip install opsqueue`,`uv install opsqueue` etc.)
23+
1. Install the Opsqueue binary, using `cargo install opsqueue` (if you do not have Cargo/Rust installed yet, follow the instructions at https://rustup.rs/ first) ([Rust crate page](https://crates.io/crates/opsqueue))
24+
2. Install the Python client using `pip install opsqueue`, `uv install opsqueue` or similar. ([Pypi package page](https://pypi.org/project/opsqueue/))
3125

3226
### 2. Create a `Producer`
3327

@@ -118,9 +112,9 @@ There are four main components:
118112
* Producer Client (used to generate and send work to Opsqueue, and optionally receive results)
119113
* Consuumer Client (used to execute chunks of work that was sent to Opsqueue)
120114

121-
## For users: Including Opsqueue in other repos
115+
## For Nix users: Including Opsqueue via Nix
122116

123-
Opsqueue's client libraries are available through `niv`.
117+
Opsqueue's client libraries and binary itself are also available through `niv`.
124118

125119
1. Add opsqueue to your `nix/sources.json`, possibly by using `niv add https://github.com/channable/opsqueue`
126120
2. Package the now available `opsqueue` library as part of your overlay, using e.g.
@@ -129,8 +123,6 @@ Opsqueue's client libraries are available through `niv`.
129123
opsqueue = self.callPackage (sources.opsqueue + "/libs/opsqueue_python/opsqueue_python.nix") { };
130124
```
131125

132-
An example to the changes required to your repo's nix overlay [can be found here](https://github.com/channable/ai/pull/763/files).
133-
134126
## For devs modifying Opsqueue: Building, running, testing
135127

136128
The [just](https://github.com/casey/just) command runner is used to wrap common commands.

libs/opsqueue_python/README.md

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,92 @@
11
The Python client library for the Opsqueue lightweight batch processing queue system.
22

3-
## Installation instructions
3+
Find the full README with examples at https://github.com/channable/opsqueue
4+
5+
## Getting Started:
6+
7+
### 1. Grab the `opsqueue` binary and the Python client library
8+
9+
1. Install the Opsqueue binary, using `cargo install opsqueue` (if you do not have Cargo/Rust installed yet, follow the instructions at https://rustup.rs/ first)
10+
2. Install the Python client using `pip install opsqueue`, `uv install opsqueue` or similar.
11+
12+
### 2. Create a `Producer`
13+
14+
```python
15+
import logging
16+
from opsqueue.producer import ProducerClient
17+
from collections.abc import Iterable
18+
19+
logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.DEBUG)
20+
21+
def file_to_words(filename: str) -> Iterable[str]:
22+
"""
23+
Iterates over each word and inter-word whitespace strings in a file
24+
while keeping at most one line in memory at a time.
25+
"""
26+
with open(filename) as input_file:
27+
for line in input_file:
28+
for word in line.split():
29+
yield word
30+
31+
def print_words(words: Iterable[str]) -> None:
32+
"""
33+
Prints all words and inter-word whitespace tokens
34+
without first loading the full string into memory
35+
"""
36+
for word in words:
37+
print(word, end="")
38+
39+
def main() -> None:
40+
client = ProducerClient("localhost:3999", "file:///tmp/opsqueue/capitalize_text/")
41+
stream_of_words = file_to_words("lipsum.txt")
42+
stream_of_capitalized_words = client.run_submission(stream_of_words, chunk_size=4000)
43+
print_words(stream_of_capitalized_words)
44+
45+
if __name__ == "__main__":
46+
main()
47+
```
48+
49+
### 3. Create a `Consumer`
50+
51+
```python
52+
import logging
53+
from opsqueue.consumer import ConsumerClient, Strategy
54+
55+
logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.INFO)
56+
57+
def capitalize_word(word: str) -> str:
58+
output = word.capitalize()
59+
# print(f"Capitalized word: {word} -> {output}")
60+
return output
61+
62+
def main() -> None:
63+
client = ConsumerClient("localhost:3999", "file:///tmp/opsqueue/capitalize_text/")
64+
client.run_each_op(capitalize_word, strategy=Strategy.Random())
65+
66+
if __name__ == "__main__":
67+
main()
68+
```
69+
70+
71+
4. Run the Producer, queue and Consumer
72+
73+
- Run `opsqueue`.
74+
- Run `python3 capitalize_text_consumer.py` to run a consumer. Feel free to start multiple instances of this program to try out consumer concurrency.
75+
- Run `python3 capitalize_text_producer.py` to run a producer.
76+
77+
The order you start these in does not matter; systems will reconnect and continue after any kind of failure or disconnect.
78+
79+
By default the queue will listen on `http://localhost:3999`. The exact port can of course be changed.
80+
Producer and Consumer need to share the same object store location to store the content of their submission chunks.
81+
In development, this can be a local folder as shown in the code above.
82+
In production, you probably want to use Google's GCS, Amazon's S3 or Microsoft's Azure buckets.
83+
84+
Please tinker with above code!
85+
If you want more logging to look under the hood, run `RUST_LOG=debug opsqueue` to enable extra logging for the queue.
86+
The Producer/Consumer will use whatever log level is configured in Python.
87+
88+
More examples can be found in `./libs/opsqueue_python/examples/`
489

5-
1. Install the Python client using `pip`, `uv` or similar.
6-
2. Install the Opsqueue binary, using `cargo install opsqueue` (if you do not have Cargo/Rust installed yet, follow the instructions at https://rustup.rs/ first)
7-
3. Enjoy!
890

991
## More Info
1092

0 commit comments

Comments
 (0)