Skip to content

Conversation

@AlysonRog
Copy link
Collaborator

Tâche Wrike: https://www.wrike.com/workspace.htm?acc=2548665#/folder/1747059856/tableV2?sidePanelItemId=1764894069&spaceId=1626668175&viewId=403308094
(Specs et tâches non renseignées dans Tuleap pour l'instant)

L'objectif de ce POC était d'implémenter la structure de projet tel que décrit dans cette présentation en utilisant le framework CAF et Xmake pour la chaine de compilation: https://iconeus.sharepoint.com/:p:/r/sites/Medicaldevice/_layouts/15/Doc.aspx?sourcedoc=%7BDCE286E5-C7E6-4554-8F2E-01B4E4C3CB49%7D&file=CAFArchiPresentation.pptx&action=edit&mobileredirect=true

Voir le README pour les items manquants qui sont hors scope de cette livraison.

Copy link
Collaborator

@danieleTrimarchi danieleTrimarchi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job, thanks for sharing !

Globally, I suggest to add documentation to make this more clear for newcomers.

The documentation should consist of :

  • appropriate naming (classes, variables)
  • relevant comments where necessary
  • documentation (sketches, ULM diagrams, online sphynx-based docs. If possible, Sphynx based docs would be compilable from both windows and linux => easier the docs is to generate, better it is :) )
  • unit tests showing the usage of the code

void initLoggerImpl(const LoggerConfig& cfg)
{
std::error_code ec;
std::filesystem::create_directories(cfg.log_dir, ec);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

si this not redundant wrt the code @l.71 ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code was a work in progress and not yet finished. And indeed there was an issue with dual directory creation ^^'. It is fixed now with the new implementation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shall this config (or part of it) not rather be a runtime-loadeable file ?
ie: enable_console_output, Rotation settings,

Copy link
Collaborator Author

@AlysonRog AlysonRog Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I intend to add a configuration file with a dedicated parser that is able to populate this LoggerConfig object. And you are right this is an important feature to have on a system to enable debug logs for investigation.
coming soon :3

{
return {[self](caf::get_atom)
{
return self->make_observable().iota(1).take(5).to_stream(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some comments on this function. While the role of the static sourceFun is clear, its implementation is not.
What is the chain : make_observable().iota(1).take(5) ?
where do you define that "int-flow" actually returns ints ?

edit => please add a reference to your source : https://actor-framework.readthedocs.io/en/latest/core/DataFlows.html

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is a dummy observer just to test the stream pattern from CAF. This is going to change soon with the addition of a real acquisition and processing stream.

* @brief Consumes a stream from a source actor and forwards each item to one or more
* destination actors.
*
* @tparam Dests Variadic template parameter pack representing the types of destination
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

variadic template ? I see a std::vectorcaf::actor

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right this was from a previous version. Removed

[=](caf::stream s)
{
// Turn the stream handle into an observable, then consume it.
self->observe_as<int>(s, 50u, 10u)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not find observe_as in the CAF documentation ( I do find observe_on though )
how reliable is this documentation ? did you build the doc locally to work with the latest version ?

https://actor-framework.readthedocs.io/en/latest/core/DataFlows.html

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can find documentation about flow/stream with CAF here: https://www.interance.io/learning/cpp/guide/flows-part-1 (this website is a little bit better documented)

SessionManager::SessionManager(caf::actor_system& system)
{
// Spawn acquisition view model actor.
// STATEFUL to keep the state of the display.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is the actor in charge for the GUI/Display, wont it be more explicit to name it GUIActor ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No this is the actor in charge of keeping the display state and logic. Another actor may be needed for the GUI part. I am not sure yet...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the comment was misleading and is here because I intended to call the viewer AcquisitionView. I have renamed it into echoViewer ^^

* @brief Base class for the workflows. This class handles the specialization behavior
* between the different types of workflows (Neonate, Neuroradiology etc). It holds a
* state machine that guides the session through the different workflow steps.
*/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the state machine is not yet there I guess..? : )

Besides, the role of the workflow and its interactions with the other components (echo_viewer_actor, acquisitionModuleActor) is not very clear to me.

I guess :

  • the workflow interacts with the GUI to guide the user trough the initial configuration steps => the GUI is modified by the workflow
  • the workflow interacts with the Acquisition to setup the sequences, define the accepted probes

Would you detail this point in some additional comments

Copy link
Collaborator Author

@AlysonRog AlysonRog Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is normal to be puzzled. Some propositions about the design still need to mature.
For now I intend to have:

  • the view-model (echoViewer for now here) that communicates with the GUI and may communicate with the workflowManager depending on the user interaction (start of acquisition, start of post-processing, retake etc). And the workflowManager may notify to the view_model of a new state in the workflow that may affect the GUI (depending on the view-model).
  • the workflow is the only one to send messages to the acquisitionModule. and the AcquisitionModule flows down acquired data to the actors that the WorkflowManager gave to the AcquisitionModule.

This is all going to be documented in the Detailed Architecture for which an overview will be presented in a TDR (end of January or beginning of February). This Detailed Architecture document shall be the ground truth for the design and be updated accordingly to the software updates. Duplicating the information in comments duplicates the information and increases the risk of forgotten and outdated documentation.

// Handle acquisition request (one day it will be a call to Moduleus
// facade)
AcquisitionModule acqModule;
acqModule.acquisitionRequest(parameterValue);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarify by means of a comment when and how this lambda is called.

The question to be answered is : what is the interaction between the acquisitionRequest and the workflow ?

The comment should point to : workflow_actor::behavior_type workflow_actor_state::make_behavior()

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same answer that above. the design still needs to mature and interactions between actors would be better documented in a single place which would be the Detailed Design document.

return ([](caf::get_atom) { std::cout << "" << std::endl; });
}

TEST("a simple test")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please implement some tests : these are a great way to explicit the intended use of the code

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CAF has not documented the way to test unitarily CAF actors through messages yet... Besides AcquisitionModuleActor is still a dummy actor. Unit test will be necessary when it will start to have real behavior.


TEST("a simple test")
{
check_eq(1, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please implement some tests : these are a great way to explicit the intended use of the code

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CAF has not documented the way to test unitarily CAF actors through messages yet... Besides AcquisitionModuleActor is still a dummy actor. Unit test will be necessary when it will start to have real behavior.

catch (std::exception& e)
{
std::cerr << "unhandled exception: " << e.what() << "\n";
medlog::shutdown();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have done some modification to have a Logger class that shall be instantiated to initialize the logging resources. Its destructor performs the spdlog shutdown and the reset of global variables. It seems to me that the finally is now unnecessary as resources are properly managed now and we are sure that Logger's destructor is called with the stack unwinding. Correct me if I am wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants