Consigli su ottimizzazione struttura

Ciao,
sono riuscito ad implementare quasi tutto, il sistema gira più o meno come dovrebbe. Ora vorrei fare qualche miglioria e non essendo un programmatore C/C++ (programmo altro di professione), sono in cerca di consigli.

Il sistema riceve comandi json-rpc usando come trasporto sia MQTT che WebSocket, entrambi in modalità asincrona . Nel mio loop c'è solamente un controllo periodico per riconnettere il wifi in caso la connessione dovesse cadere, tutto il resto gira in task rtos separati.

La domanda è: appurato che i comandi che json-rpc dovrà eseguire sono in comune ad entrambi i trasporti, come posso strutturare il tutto in maniera ottimale ? Al momento ho una classe Executor che viene instanziata dall'evento wsOnEvent del server websocket. Dentro l'evento faccio il parse del json-rpc, leggo il comando da eseguire, instanzio la Executor passando un puntatore alla funzione comando vera e propria (il comando è una semplice funzione dentro un namespace Commands). la Executor quindi mi crea un task dedicato con il comando stesso come funzione da eseguire. Tutto il codice è dentro il comando, compreso quello per rispondere al websocket.

Il sistema funziona, ma non mi piace. in particolare non mi piace il grossolano namespace con i vari comandi all'interno. La classe Executor mi serve perchè la uso come "appoggio" per passarmi dei parametri all'interno del task, diversamente non appena il task viene instanziato, perderei i parametri (che sono passati per forza come puntatori al task freertos) venendo eliminati. Così facendo invece l'Executor mi resta instanziato (e con esso tutti i puntatori) finchè non lo distruggo da dentro il task stesso.

Pseudocodice (ma neanche troppo) per rendere l'idea:

if (method.equals("type.mioComando"))
{
   Executor *exec = new Executor();
   exec->execute((const char *)json, &Commands::mioComando, wsClientId);
}






typedef void (*execTask)(void *ptr);

void Executor::execute(String json, execTask task, uint32_t wsClientId)
{
   this->wsClientId = wsClientId;
   this->requestJSON = json;

   DynamicJsonDocument docRequest(2048);
   deserializeJson(docRequest, json);
   String requestId = docRequest["id"];

   this->taskId = requestId ? requestId : "";

   BaseType_t result = xTaskCreatePinnedToCore(
     task,                 // Task function.
     this->taskId.c_str(), // name of task.
     4 * 1024,             // Stack size of task
     this,                 // parameter of the task
     1,                    // priority of the task
     &this->taskHandle,    // Task handle to keep track of created task
     1);

   if (result != pdPASS)
   {
     Serial.printf("executor.cpp: task creation failed: %i\n", result);
   } else {
     Serial.println("executor.cpp: created task with id " + this->taskId);
   }
}






namespace Commands
{
   void mioComando(void *pvParameters)
   {
     {
         UBaseType_t uxHighWaterMarkStart = uxTaskGetStackHighWaterMark(NULL);

         Executor *exec = (Executor *)pvParameters;
         uint32_t wsClientId = (uint32_t)exec->wsClientId;
         String jsonRequest = (String)exec->requestJSON;


         // Faccio cose
         // ............


         DynamicJsonDocument docRequest(2048);
         deserializeJson(docRequest, jsonRequest);
         String jsonrpc = docRequest["jsonrpc"];
         String method = docRequest["method"];
         String requestId = docRequest["id"];

         DynamicJsonDocument docResponse(2048);
         docResponse["jsonrpc"] = jsonrpc;
         docResponse["id"] = requestId;
         docResponse["result"] = true;

         String jsonResponse;
         serializeJson(docResponse, jsonResponse);         

         webserver.websocket->text(wsClientId, jsonResponse);

         delete exec;
      }

      vTaskDelete(NULL);
   }
}

Consigli ? Così non mi piace proprio. Si può fare sicuramente meglio. Saprei farlo in php senza impazzire con sti puntatori, passerei i parametri necessari direttamente al task e finirebbe li....

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.