On Sun, Jan 15, 2023 at 9:17 AM Klemens Morgenstern via Boost
wrote:
[snip]
Review ========
Please explicitly state that you either *accept* or *reject* the inclusion of this library into boost. Also please indicate the time & effort spent on the evaluation and give the reasons for your decision.
The review is open to anyone who is prepared to put in the work of evaluating and reviewing the library. Prior experience in contributing to Boost reviews is not a requirement.
Some questions to consider:
- Does this library bring real benefit to C++ developers for real world use-case?
I think so, yes.
- Do you have an application for this library?
I do not.
- Does the API match with current best practices?
No. In particular, the API requires the user to write lots of Redis
strings by hand. A typo will not be detected until runtime. The set
of Redis keywords is fixed; there's no reason not to make an
enumeration of them all, like this:
enum class cmd {
ACL_CAT, // List the ACL categories or the commands inside a category
ACL_DELUSER, // Remove the specified ACL users and the associated rules
ACL_DRYRUN, // Returns whether the user can execute the given command
// without executing the command.
ACL GENPASS, // Generate a pseudorandom secure password to use for ACL users
ACL_GETUSER, // Get the rules for a specific ACL user
ACL_LIST, // List the current ACL rules in ACL config file format
ACL_LOAD, // Reload the ACLs from the configured ACL file
ACL_LOG, // List latest events denied because of ACLs in place
// ... etc.
};
I actually did all of them to see how much effort it would take. It
took me about 20 or 30 minutes, working from the list on the Redis
website (I just copy/pasted the commands listed at
https://redis.io/commands/).
Further, when enqueuing commands, there's no checking that a command
and its arguments make sense together. For instance, here is some
example code from the docs:
resp3::request req;
req.push("HELLO", 3);
req.push("HGETALL", "hset-key");
req.push("QUIT");
If I change that last line to:
req.push("QUITE");
or to:
req.push("QUIT", "oops");
or even to:
auto it = 42, getting = 13;
req.push("QUIT", this, is, getting, "ridiculous");
... the code is well formed, but nonsensical. I'd like the lib to
know that "QUITE" isn't a thing, and that "QUIT" takes no arguments,
and fail to compile if I mess any of this up via typo or copy/paste.
One possible fix would be to change resp3::request::push*() to take a
non-type template parameter that can be used to check the args:
template
- Is the documentation helpful and clear?
It is geared more towards users who already know all about Redis, and it is more reference-oriented. There is a real lack of the tutorial-style docs that Boost is known for. Boost reaches a really wide audience. There are a lot of people who might not be very DB-savvy, who might want to use Aedis, since "Hey, I already have Boost, why not use this DB library?" There are no docs for such users. For Redis aficionados, there should also be a step-by-step guide to how to do real work with the lib. The examples seem pretty good. I think one or more of them need to be integrated into the docs as a tutorial. There are lots of examples of other Boost libs that do this. The reference documentation is often too spare. For instance: https://mzimbres.github.io/aedis/classaedis_1_1resp3_1_1request.html#a9951b1... I must convert data to a string. Are there any requirements on the string? Can it have internal nulls, characters requiring escaping, etc.? I don't necessarily think that the docs need to talk about this in the reference section, but since this is not covered in the also-spare tutorial section, how am I supposed to know what the string requirements are? The Serialization section in https://mzimbres.github.io/aedis/index.html is similarly problematic. This is the example: // User defined type. struct mystruct {...}; // Serialize it in to_bulk. void to_bulk(std::pmr::string& to, mystruct const& obj) { std::string dummy = "Dummy serializaiton string."; aedis::resp3::to_bulk(to, dummy); } I was baffled by this at first reading. Why is obj there? It is unused. If "Dummy serializaiton string." were replaced with /* stringify obj here */, the example makes sense. I did not understand that I was supposed to do that until I read the reference mentioned earlier. There are a lot of things like this in the docs -- more than I have time to list. I don't think the docs are up to the Boost standard.
- Did you try to use it? What problems or surprises did you encounter?
I did not.
- What is your evaluation of the implementation?
I did not look at much of the implementation. What little I did see seemed reasonable.
Additionally, stating your knowledge of redis and asio would be helpful for me.
I've used ASIO a lot, and never used Redis. I vote to REJECT. If the library could be refactored so that the user-facing interface was more friendly, I would change my vote. Zach