Show HN: Goqite, a persistent message queue Go library built on SQLite (goqite.com)
I wanted to build a persistent message queue based on SQLite, because that's what I'm using for my main state anyway. This gives me ACID across state and messaging, which is nice!
I've been inspired by the terminology of AWS SQS for this, but it's obviously much simpler.
Maybe you can use it too. :)
69 comments
[ 0.27 ms ] story [ 136 ms ] thread"goqite (pronounced Go-queue-ite) is…"
Also, yes, I will take on that risk. As anyone who has ever been at the receiving side of an issue tracker knows, not all feedback is equal. I appreciate taking the time to provide feedback, though, but I always reserve the right to not act on it.
If 7 people tell you that "go kite" is not a great name for an important database system, I don't know what to tell you other than "consider the feedback".
(But I can see how that could be clearer from the example code. I think I'll add that as comments. Thank you for the feedback!)
IMO it should become more opinionated and stricter. I'd honestly pay to buy a license for SQLite with the legacy baggage removed and rewritten to be as strict as PostgreSQL or more. Well... basically embedded PostgreSQL I guess.
It uses bbolt/bolt instead of sqlite. It was for use on shared servers that had questionable uptime.
I haven't touched it in a long time, but it served its purpose well
Also supports both an HTTP and Redis API.
https://github.com/tomarrell/miniqueue
As noted elsewhere here, it was important to me to use SQLite, since that's what I use as the storage layer already. But I've added HTTP adapters for remote clients.
I hadn't thought of using a different remote API, interesting idea. Thank you for the pointer!
Though I'd guess tools like `c2rust` don't produce idiomatic Rust code and it can be a lot of effort to turn that into proper Rust. That's likely the biggest reason.
Check the source, that's essentially what it is. But you get this particular design, the tests etc. for free, so if you value your time, maybe this is worth something to you. Maybe not though. Either way, it's fine.
Could you clarify?
[0]: https://github.com/litements/litequeue
(Thank you for all the comments!)
> 30 minutes later they open a new PR to address a comment left by [an HN user](https://news.ycombinator.com/item?id=39673795)
I think this person might like coding
It started on top of bbolt, but over time moved a completely custom implementation. The main reason for this was performance, but I also wanted to run a lot of queues, so each one had to be as light as possible. On top it even provides some indexing capabilities, which (when enabled) allow for quick find by key and time.
I would think that having a small chance of message loss due to writing to an append only log in batches might be a reasonable trade off for many things (if that is how it works).
In klevdb you can control the fsync yourself - using AutoSync you can ask it to perform fsycn after each Publish, which currently is best effort put on disk. Of course in this case performance suffer dramatically (as you would expected, esp if you don't batch). You can also not use AutoSync and control it yourself (klevdb exposes Sync), deciding what kind of message loss you are prepared to deal with. The benchmarks you see run without AutoSync, to highlight what kind of raw throughput klevdb is capable of.
And yeah, klevdb is basically an append-only log. Of course, you can delete messages from it, but this is done in parallel, where the segment is being copied without the messages you want to delete, then replaced with a single mv system call. Rewriting the head segment (e.g. the one you are writing to) is not always possible (since there could be messages the rewriter haven't seen), but will eventually succeed (once the head segment is no longer a head).
Hope this answers your questions, and if not, happy to expand more. I've been contemplating on implementing transactions on top of klevdb, but haven't quite figured out if I need them or not.
Edit: spelling and grammar
Cool project! Would love to implement something similar in another language and maybe compare performances, even though I guess they would be very similar since there’s gonna be SQLite under the hood.
Thanks! Doing it in another language would be almost trivial, there's really not a lot of code involved. I've focused mostly on making a nice, easy to use API for the common cases. No more, no less.