-
Notifications
You must be signed in to change notification settings - Fork 7.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature(console): add command user context support (IDFGH-11280) #12436
Conversation
👋 Welcome alonbl, thank you for your first contribution to 📘 Please check Contributions Guide for the contribution checklist, information regarding code and documentation style, testing and other topics. 🖊️ Please also make sure you have read and signed the Contributor License Agreement for espressif/esp-idf project. Pull request review and merge process you can expectEspressif develops the ESP-IDF project in an internal repository (Gitlab). We do welcome contributions in the form of bug reports, feature requests and pull requests via this public GitHub repository.
|
2f687ce
to
0147a20
Compare
@alonbl We're taking a look at this now and will come back here soon. |
@alonbl We discussed the PR and in general, it looks good! We have one concern, however: The current version would add a global context value which is passed to any command callback registered with |
Hi, Global variables are evil, the libraries should be designed to minimize their use, this helps to keep track of resources. Look at the http_server implementation as a reference which is done nicely. Having application context managed in several places, aka passed as parameters to functions (at is should) and have it also copied in global variable is bad practice as the two (or more) require synchronization. The next stage of this patch would be the ability to register a context per command using The end use case is the following: In application each module registers its own console commands as decoupled from one from another, a command of each module should be invoked in the correct context. As you well know, the console module is very important to embedded system and is missing a lot of love, for example:
What do you think? I can workout a modified patch that will allow a context per command (step#2), will it be better? Thanks, |
Yes, one context per command sounds more flexible to us. If you have any question, feel free to come back to us, we'll provide help where possible. Thanks a lot already! |
Don't the two contexts ("per command" and "per esp_console_run invocation") solve different kinds of problems?
So one solution doesn't seem to be "better" or "worse" than the other, they seem to solve different problems.
Could you please clarify what specific issue (other than global variables being evil) did you run into trying to implement this? For example, consider multiple "modules" providing console commands: Each module is decoupled from the other module, and each has its own set of commands. There is shared state (static variables) within each module, but the modules don't have shared state between themselves. I guess your use case is somewhat different, could you please explain in more detail? (I am not debating whether having user-supplied context in the API is good or not; I would just like to understand the issue you are running to better.) |
0147a20
to
be61c4a
Compare
Thank you for your feedback, I pushed an alternate version in which the context is per command. Implementation note: I did not want to add the context to Regards, |
TEST_ESP_OK(esp_console_cmd_register(&s_quit_cmd)); | ||
TEST_ESP_OK(esp_console_register_help_command()); | ||
|
||
TEST_ESP_OK(esp_console_start_repl(s_repl)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for unit test purposes, you don't need to start the whole REPL. You can call esp_console_run
and verify that the expected callback got called with the expected context. (Either by setting some variable from the callback, or by temporarily substituting stdout
using open_memstream
and then asserting that the expected string was printed by the callback.)
In this case, the test doesn't need the [ignore]
tag and will be run automatically in CI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, I think.
be61c4a
to
360360e
Compare
Current implementation implicitly forces the developer to use global variables to enter its context during the command invocation, this change enables each module to register a context for command to find without the need to manage global variables. No API breakage. Fields added: esp_console_cmd_t::func_context - (*)(int argc, char **argv, void *context) Functions added: esp_err_t esp_console_cmd_set_context(const char *cmd, void *context) Usage: esp_console_cmd_register(&cmd)); esp_console_cmd_set_context(cmd.command, (void *)"context")); Signed-off-by: Alon Bar-Lev <[email protected]>
360360e
to
867f9d0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alonbl The current approach looks good. Thanks for adding the unit test! We'll handle this and after going through internal CI and reviewing, it will appear on master if there are no concerns. We'll keep you updated.
sha=867f9d0dbbe130f4ea46bdf87a0b28d1cbcd3c91 |
@alonbl We've merged the code to our internal code base, from where it will be synced to the master branch soon. The code looks slightly different now as we adjusted the naming a bit, but your authorship has been retained, of course. |
@alonbl The change has been merged to master. However, we'll change the API once more so that the context can be set with |
Hi @0xjakob, |
@alonbl Sorry, it's a typo. I edited my post. It means that |
All the relevant code is merged. Hence, we're closing this PR (to mark it as finished). |
Outline
Current implementation implicitly forces the developer to use global variables
to enter its context during the command invocation, this change enables each
module to register a context for command to find without the need to manage
global variables.
No API breakage.
Fields added
Functions added
Usage