Questions in a separate service/process#231
Conversation
Pull Request Test Coverage Report for Build 2847033928
💛 - Coveralls |
6c776b8 to
9661d86
Compare
|
One thing that is beyond me: when I put the Software service Now that I think of it, probably the product selection react component needs to include the questions component? Haven't checked yet. |
|
[..]
Yes, we decided to not put the questions on the product selection page because we did not want other questions (like decrypting storage devices and so on) to come on top of the product selection. We consider product selection the very first step. Of course, as everything related to D-Installer, we can discuss and decide something different. :-) |
|
I don't understand what scenario Counterpoint: @joseivanlopez as you designed this, what do you think? |
bbe9ed6 to
86441c1
Compare
still in the same old service busctl --system \ call org.opensuse.DInstaller \ /org/opensuse/DInstaller/Questions1 \ org.opensuse.DInstaller.Questions1 New sasas "should I stay or should I go" 2 yes no 1 yes
a later commit makes this run only when an env variable is set
To investigate: when I triggered it locally in product selection, the web frontend was not picking it up. To detect such cases, the front end could set an Asked(displayed) property and the backend could fail a question that was not asked after a timeout. Better than infinitely waiting for a question that the user did not see?
there are some ugly hacks with private members and with making a stub for the question proxy
the #wait implementation is still a hack
also fix some code formatting issues
like DInstaller::Question does. Which fixes a stupid bug where "nineveh" == :nineveh never matches
Both - DInstaller::QuestionsManager - DInstaller::DBus::Clients::QuestionsManager will #wait for the questions passed as argument. For the client case this is rather academic as the #ask interface supports only one question at a time. But in the main service we could be asking a question while another service is waiting for an answer to another, and that is not our business.
86441c1 to
7120bf4
Compare
| # Stupid but simple way: poll the answer property, sleep, repeat | ||
| loop do | ||
| questions = questions.find_all { |q| !q.answered? } | ||
| break if questions.empty? |
There was a problem hiding this comment.
why not break if questions.all?(&:answered?)
There was a problem hiding this comment.
Because our D-Bus clients do not cache properties and this way we don't make calls about questions that we already know are answered.
There was a problem hiding this comment.
so please document it. or maybe use better variable name.
| dbus_object.Finish | ||
| end | ||
|
|
||
| def testing_question |
There was a problem hiding this comment.
leftover of testing method?
| dbus_method(:Install) { install } | ||
| dbus_method(:Finish) { finish } | ||
|
|
||
| dbus_method(:TestingQuestion) { backend.testing_question } |
There was a problem hiding this comment.
testing method leftover?
| dbus_q = @service.get_node(question_path)&.object | ||
| raise ArgumentError, "Object path #{question_path} not found" unless dbus_q | ||
| raise ArgumentError, "Object #{question_path} is not a Question" unless | ||
| dbus_q.is_a? DInstaller::DBus::Question |
There was a problem hiding this comment.
please do not use trailing if/unless when it is not single line
service/lib/dinstaller/manager.rb
Outdated
| if ENV["DINSTALLER_TEST_QUESTIONS"] == "1" | ||
| testing_question | ||
| software.testing_question | ||
| end |
| loop do | ||
| on_wait_callbacks.each(&:call) | ||
| questions = questions.find_all { |q| !q.answered? } | ||
| break if questions.empty? |
There was a problem hiding this comment.
same here. I would use single line more readable break if questions.all?(&:answered?)
service/lib/dinstaller/software.rb
Outdated
|
|
||
| # TODO: if a question is asked here, there is no web UI to handle it. | ||
| # Is it a problem? | ||
| # testing_question if ENV["DINSTALLER_TEST_QUESTIONS"] == "1" |
There was a problem hiding this comment.
Yes, but a good opportunity to ask about the TODO:
What should happen when some code asks a Question and the web UI has no component to display it?
Currently the code deadlocks waiting for an answer that will not come.
Arguably it will only happen during development.
We could add a displayed? property to Questions and raise an error if a Question is not displayed within 20 seconds.
| describe "#config_phase" do | ||
| before do | ||
| allow(subject).to receive(:testing_question) | ||
| allow(software).to receive(:testing_question) |
There was a problem hiding this comment.
Well, now you get me. I am no longer sure if that testing question is testing leftover or not. But in general I do not like it :)
|
With commit 75d9464 I am removing the testing questions. When we add some actual question, that code can serve as usage example of the API. |
compared to DInstaller::QuestionsManager - it does not need callbacks like #on_add - #add will not return an error. CanAskQuestion#ask ignores them anyway.
4d6018e to
ea77d16
Compare
Yes, it doesn't care. If
The idea is to avoid adding the very same question: Note that the
The only important thing is to avoid duplicate questions. Failing "helps" to identify whether the question was already added. But, as you suggested,
|
Problem
The user-facing callbacks, aka Questions (dbus-api) have so far been limited to a single process/service. However, a major use case are the packager callbacks, and there is a separate o.o.DInstaller.Software service.
All the questions should live in one service. Originally we thought that it should be a separate process hosting only the questions, but so far that hasn't been necessary, the main service is able to host them.
At least a D-Bus call to add a new question is needed.
Solution
The main idea of the solution is: keep the existing
CanAskQuestionsmixin, and let it be used the same way, with the questions service being either in the same process or not.This is achieved by providing
def questions_manager { DInstaller::DBus::Clients::QuestionsManager.new }with the same API asDInstaller::QuestionsManager.Testing
Screenshots
(No new UI)